什么是在哈斯克尔,为什么没有它这个功能不起作用?

bad*_*ash 4 haskell types maybe

我有以下函数,就像一个索引操作符:

let {
  index :: [a]->Int->Maybe a
  index [] i = error "Empty list"
  index l i = if i <= ((length l) - 1) && i >= 0 then 
      Just(l !! i) 
    else
      error "Index out of bounds"
}
Run Code Online (Sandbox Code Playgroud)

现在,我最初在没有使用的情况下编写了这个Just(我仍然不明白google搜索后它是什么):

let {
  index :: [a]->Int->Maybe a
  index [] i = error "Empty list"
  index l i = if i <= ((length l) - 1) && i >= 0 then
      (l !! i) 
    else
      error "Index out of bounds"
}
Run Code Online (Sandbox Code Playgroud)

对我而言,上述功能非常有意义.因为在这里我有一个不接受"泛型类型"列表的功能,a并且Int这是该指数和返回Maybe值的类型a或者抛出运行时异常.但是,我不明白GHCi告诉我这一点:

<interactive>:1:120:
Couldn't match type `a' with `Maybe a'
  `a' is a rigid type variable bound by
      the type signature for index :: [a] -> Int -> Maybe a
      at <interactive>:1:34
Expected type: [Maybe a]
  Actual type: [a]
In the first argument of `(!!)', namely `l'
In the expression: (l !! i)
Run Code Online (Sandbox Code Playgroud)

现在,为什么GHCi会与类型混淆,l为什么它会期待类型列表Maybe a?最后,如何Just解决问题?

Sar*_*rah 6

您已在类型注释中明确声明函数index返回了一个Maybe a.

也许是Haskell中定义的数据类型:

data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)

也就是说,它有两个值构造函数,Just :: a -> Maybe aNothing :: Maybe a.因此,为了使您的功能正常工作,它必须返回a Just a或a Nothing.

这也意味着你应该能够通过一些思考来删除你的错误语句并编码实际的错误Nothing(即我们超出界限,这里没有元素!)并且只有Just a在有意义的情况下才返回结果.

  • 为了对称起见,在关于构造函数的句子中编写`Nothing :: Maybe a`而不是`Nothing`可能会很好,因为你已经给出了`Just`的类型,以防OP认为两者是不同的野兽. (2认同)