首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >俄罗斯方块卡混合单进纯码

俄罗斯方块卡混合单进纯码
EN

Stack Overflow用户
提问于 2020-01-19 12:30:31
回答 2查看 103关注 0票数 1

我试图在haskell实现vulkan教程的一些部分。

目前,我一直试图从c中翻译这段代码:

代码语言:javascript
运行
复制
for (const char* layerName : validationLayers) {
    bool layerFound = false;

    for (const auto& layerProperties : availableLayers) {
        if (strcmp(layerName, layerProperties.layerName) == 0) {
            layerFound = true;
            break;
        }
    }

    if (!layerFound) {
        return false;
    }
}

return true; 

到目前为止,我已经到了这个地步:

代码语言:javascript
运行
复制
-- This has type (Int -> Text) -> Bool
let partOne = all (`elem` requiredValidationLayers) . flip map [0 .. realCount-1]
-- This has type Int -> IO Text
let partTwo i = do
        let layerProperty = advancePtr layerProperties i
        myField_ <- readStringField @"layerName" layerProperty
        pure $ toS myField_ :: IO Text

我觉得这里有我所有的部分,但我也可能走向一个完全错误的方向。

我怎么把这些东西放在一起?

谢谢

PS:好的,我只是注意到集合包含检查很可能是相反的--没关系,为了这个问题,让我们假装它真的很好

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-19 15:27:53

谢谢所有的评论,我想我现在明白了:)

如下所示(在do块的IO ()中):

代码语言:javascript
运行
复制
supportedLayers <- for [0 .. realCount-1] $ \i -> do
    let layerProperty = advancePtr layerProperties i
    myField_ <- readStringField @"layerName" layerProperty
    pure $ toS myField_ :: IO Text
return $ requiredValidationLayers `includes` supportedLayers

哪里

代码语言:javascript
运行
复制
includes :: Eq a => [a] -> [a] -> Bool
includes a b = all (`elem` b) a
票数 1
EN

Stack Overflow用户

发布于 2020-01-19 15:33:35

我要从一些假设开始:

有一个类型data Layer = ...

  • You有一个类型别名type Name = String

  • You有一些函数layerName :: Layer -> Name

我将介绍纯函数的定义,这并不是因为它非常重要,而是因为它使用了一种从纯函数转换为纯函数(即IO-dependent)代码的技术。

给定的层是否有给定的名称?

首先,您有基本操作。

代码语言:javascript
运行
复制
strcmp(layerName, layerProperties.layerName) == 0

这是一个简单的Haskell函数,它接受一个Name和一个Layer,如果该层具有给定的名称,则返回True

代码语言:javascript
运行
复制
hasName :: Name -> Layer -> Bool
hasName name layer = name == layerName layer

几个层中的一个有几个名称中的一个吗?

但是我们没有一个名称或层,我们有每一个的列表。通过使用列表的Applicative实例来建模不确定性,我们可以轻松地处理这一问题。

代码语言:javascript
运行
复制
import Control.Applicative

foo :: [Name] -> [Layer] -> [Bool]
foo = liftA2 hasName

我不会给这个函数取一个好名字,因为我们不需要一个。

现在,我们可以得到将每个名称与每个层进行比较的结果列表,但我们并不关心单个结果:我们只想要一个值,表示我们是否找到了匹配项。为此,我们将使用or :: [Bool] -> Bool

代码语言:javascript
运行
复制
findMatch :: [Name] -> [Layer] -> Bool
findMatch names layers = or (foo names layers)

foo非常简单,我们只需要内联它的定义,这样我们就不需要想出一个更好的名称了:

代码语言:javascript
运行
复制
findMatch :: [Name] -> [Layer] -> Bool
findMatch names layers = or (liftA2 hasName names layers)

处理IO

现在,我们假设我们已经有了作为纯值的名称和层的列表。但如果我们没有呢?如果只有从文件或其他地方读取的列表,以便有IO [Name]和/或IO [Layer],怎么办?解决方案是再次使用liftA2,但我们将使用IO实例,而不是使用Applicative的list实例。

代码语言:javascript
运行
复制
ionames :: IO [Name]
ionames = ...

iolayers :: IO [Layer]
iolayers = ...

result :: IO Bool
result = liftA2 findMatch ionames iolayers
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59810018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档