2012-07-26 162 views
4

我有以下的功能就像一个索引操作:Haskell中的Just是什么?为什么没有它,这个函数不能工作?

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" 
} 

现在,我开始写这不使用Just(和我还是不明白什么是谷歌搜索后):

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" 
} 

对我而言,上述功能非常有意义。因为这里我有一个函数,它接受'通用类型'aInt这是索引并返回Maybea的值或抛出运行时异常。但是,我不明白的地方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) 

现在,为什么GHCI感到困惑与l类型,为什么它期待Maybe a类型的列表?最后,Just如何解决问题?

+1

代码大师,现在我的代码在你编辑后看起来很舒服:) – badmaash 2012-07-26 21:03:56

+0

你真的喜欢用你最初发布的单行代码写你的定义吗? – gspr 2012-07-26 21:04:34

+1

其实,我绝对不会写这样的单行,因为我来自C++/VB.NET背景。由于Haskell为我提供了选择编写 - 编译 - 执行还是只写执行的选项,我的懒惰更喜欢第二种选择。另外,我刚开始学习它,所以只有'玩具程序'会这样写。也许我不知道我是否可以在GHCi的多行中分割我的代码,是吗? – badmaash 2012-07-26 21:12:06

回答

6

您已在类型注释中明确指出您的函数index返回Maybe a

也许是在Haskell正是如此定义的数据类型:

data Maybe a = Just a | Nothing 

即,它有两个值构造,Just :: a -> Maybe aNothing :: Maybe a。因此,为了使您的功能正常工作,它必须返回Just aNothing

这也意味着你应该能够通过一些想法去除你的错误陈述并且编码Nothing中的实际错误(即,我们超出了界限,这里没有元素!)并且仅返回结果Just a如果它是有道理的。

+2

为了保持对称性,在“Nothing :: Maybe a”而不是“Nothing”关于构造函数的句子,因为你已经给出了'Just'的类型,以防OP认为它们是不同的野兽。 – gspr 2012-07-26 20:54:50

+1

@gspr:你显然是对的!固定。 – Sarah 2012-07-26 21:02:07

+0

对,我会读更多关于价值ctors,数据类型和类型的...我认为Haskell会成为一个欢乐骑...... :) – badmaash 2012-07-26 21:18:11

1

从文档,Data.Maybe

的也许类型封装了一个可选值。类型Maybe的值可以包含a类型的值(表示为Just a),或者为空(表示为Nothing)。

如果你正在寻找一个类型Maybe Int那么你的函数将返回Nothing,或Just Int

这是一种简单的错误monad,其中所有错误都由Nothing表示。

本质上,如果Nothing返回,然后发生了一些事情导致函数无法找到结果。 Just限定符允许您使用这些Maybe类型。

1

您告诉GHC返回类型indexMaybe a。这意味着(l !! i)(由index返回的值)必须是Maybe a

由于(l !! i)被选择单个元件出名单l的,这意味着l必须按顺序[Maybe a]类型的其元件中的一个是Maybe a

lindex的第一个参数,您也告诉GHC键入[a]

这正是你的错误。 GHC正试图编制一个索引到[Maybe a]得到一个Maybe a,但它被发现被索引的东西是[a]

原因Just修复此问题,是Justa -> Maybe a类型。所以,当你说Just (l !! i)时,GHC现在看到你索引[a]得到a,然后将Just应用到导致Maybe a的那个,如预期的那样。

相关问题