我如何设置函数的签名是正确的?

IPi*_*iro 1 haskell maybe

我练了一些Haskell的了解\,case.. ofMaybe更好.

我在这里有一个小函数,Nothing如果数组为空,Just y如果y等于数组xs的头部,并且Just (tail xs)y不等于数组xs的头部,则应该返回.

我将函数的返回类型设置为,Maybe a因为在一种情况下它应该返回一个Int而在另一个中[Int].

funct :: Int -> [Int] ->  Maybe a
funct = \y xs -> case xs of
            [] -> Nothing
            xs -> if ((head xs) == y)
                        then Just y
                        else Just (tail xs)
Run Code Online (Sandbox Code Playgroud)

我错过了什么?我得到它不能匹配类型的错误a[Int].是不是aMaybe a一般的还是它的事实影响了我"拿来主义"的a作为IntJust y一部分吗?

编辑:好的我的建议是bs,我Just (tail xs)在当时和其他部分测试它,我仍然得到相同的错误.

Wil*_*sem 6

设置函数的返回类型,Maybe a因为在一种情况下它应该返回一个Int而在另一个中[Int].

Haskell是静态类型的.这意味着它不能 - 在运行时 - 具有不同的返回类型.它只能有一种返回类型.a不是ad hoc类型(在某种意义上它可以是运行时的任何类型).这意味着a将在编译时根据其他参数的类型确定.

例如,你可以编写:foo :: a -> a -> a指定如果foo需要两个Ints(在编译时再次知道),结果将是一个Int.

但是你可以Either a b说你将要么返回a Left a或a Right b.所以你可以把它重写为:

funct :: Int -> [Int] ->  Maybe (Either Int [Int])
funct = \y xs -> case xs of
            [] -> Nothing
            xs -> if ((head xs) == y)
                        then Just (Left y)
                        else Just (Right (tail xs))
Run Code Online (Sandbox Code Playgroud)

但是你的功能非常冗长,你可以使它更加清晰和紧凑,如下所示:

funct :: Int -> [Int] ->  Maybe (Either Int [Int])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
              | otherwise = Just (Right t)
Run Code Online (Sandbox Code Playgroud)

此外,我们可以将其概括为:

funct :: Eq a => a -> [a] ->  Maybe (Either a [a])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
              | otherwise = Just (Right t)
Run Code Online (Sandbox Code Playgroud)

Eq是一个类型类,指定存在(==) :: a -> a -> Bool我们可以使用的函数.否则==在函数体中使用是不可能的.

此外,我们在每个条款的头部使用模式.[]是描述空列表的模式.(h:t)另一方面,是描述包含至少一个元素的列表的模式:头部h,后跟一个(可能是空尾t).