【发布时间】:2020-05-05 16:18:20
【问题描述】:
我正在尝试在 haskell 中实现一些 vulkan-tutorial。
现在我坚持尝试从 c: 翻译这段代码
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;
到目前为止,我已经到了这一点:
-- 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:好的,我只是注意到设置包含检查可能会被反转 - 没关系,为了这个问题,让我们假装它实际上很好
【问题讨论】:
-
partTwo到底在哪里?原始代码 C 代码应该做什么? -
partTwo 接受一个整数 i 并在 c 中返回 layerProperties[i].layerName 等价物,因为 vulkan-api 如何处理这些构造,layerProperties 实际上是一个不透明的 Ptr结构数组。因此所有这些样板
-
原始c代码是一个集合包含检查:如果validationLayers的每个元素都在availableLayers中
-
写一个pure函数
f实现C代码。然后使用Control.Appicative.liftA2将其提升以使用IO操作中的值。也就是说,如果f :: [a] -> [b] -> Bool,那么liftA2 f :: IO [a] -> IO [b] -> IO Bool(特化为IO,即)。 -
除了其中一个Lists只能在IO Monad中读取,所以实际上是[Layer] -> IO [Layer] -> IO Bool。仍然举起它应该会产生类似 IO [Layer] -> IO [Layer] -> IO Bool 的东西,对吧?由于 monads 的可连接性......我稍后会以全新的心态再次查看这段代码
标签: c haskell monads code-translation do-notation