0

我试图从一个使用 do 表示法的函数返回一个 Maybe 值,但我似乎无法让它工作。这个函数需要一个字符串(“文件名”)和一个要搜索的路径...

findIn :: String -> Path -> Maybe Path
findIn search start = do
    file <- ls start
    if ((filename file) == search)
      then Just file
      else Nothing

在哪里...

ls :: Path -> Array Path
filename :: Path -> String

但是我不断收到错误“Count not match Type Array with type Maybe”,所以看起来编译器期望 do 表示法返回一个数组。我将如何返回一个可能的值?

4

2 回答 2

2

你不能像那样混合单子。

当你写:

file <- ls start

这有点像说“对于file数组中的每个值......”所以你处于多个可能值的上下文中。

但是其余的代码在 的上下文中Maybe,它只能处理一个(或零)值。

在模块Data.Foldable中有一个find函数,它通过搜索与某些条件匹配的单个项目来完成主函数的大部分工作。它的实际类型更通用,但是当限制为 Arrays 时,它是这样的:

find :: forall a. (a -> Boolean) -> Array a -> Maybe a

然后你可以写:

findIn search start = find (\x => x == search) $ ls start
于 2016-04-03T01:34:48.487 回答
1

好的,我找到了一些可行的方法,但我不确定它是否理想。

findIn :: String -> Path -> Maybe Path
findIn search start = if (length r == 1)
                      then head r
                      else Nothing
  where
    r = do
      file <- ls start
      guard $ (filename file) == search
      [file]

所以看起来 do-notation 返回一个 Array(Maybe Path) 类型的值。

于 2016-04-03T01:27:33.530 回答