Haskell中的可空列表参数

wkftcu5l  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(114)

我是Haskell的新手,我试图实现一个接受“null”参数的head函数版本

safeHead :: Maybe [a] -> Maybe b
safeHead (Just []) = Nothing
safeHead Nothing = Nothing
safeHead (Just (x:xs)) = Just x

字符串
从概念上看,它看起来没问题。但是类型系统不接受最新的等式。为什么?

• Couldn't match expected type ‘b’ with actual type ‘a’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          safeHead :: forall a b. Maybe [a] -> Maybe b
        at ch04.hs:2:1-32
      ‘b’ is a rigid type variable bound by
        the type signature for:
          safeHead :: forall a b. Maybe [a] -> Maybe b
        at ch04.hs:2:1-32
    • In the first argument of ‘Just’, namely ‘x’
      In the expression: Just x
      In an equation for ‘safeHead’: safeHead (Just (x : xs)) = Just x
    • Relevant bindings include
        xs :: [a] (bound at ch04.hs:4:19)
        x :: a (bound at ch04.hs:4:17)
        safeHead :: Maybe [a] -> Maybe b (bound at ch04.hs:3:1)

n53p2ov0

n53p2ov01#

类型签名中的类型变量,如ab

safeHead :: Maybe [a] -> Maybe b

字符串
是由函数 caller 选择的。这意味着如果有人调用你的函数,他们可以选择使用它,就好像它是,比如说,

safeHead :: Maybe [String] -> Maybe Int


在这种情况下,呼叫者对您的第三个等式不满意

safeHead (Just (x:xs)) = Just x


因为xString,而不是类型签名所暗示的Int
为了修复代码,我们需要弱化类型承诺:函数不会为所有b返回Maybe b,而只为b = a返回。

safeHead :: Maybe [a] -> Maybe a
                            -- ^ --


最后,请注意,通常这种“安全头”函数是用类型[a] -> Maybe a定义的。我想知道是否真的需要输入上的额外Maybe。额外的Maybe没有问题--但它可能不是您实际需要的。

ewm0tg9j

ewm0tg9j2#

它几乎是正确的,除了类型。结果是Maybe a,因为我们取列表的第一项:

safeHead :: Maybe [a] -> Maybe a
safeHead (Just []) = Nothing
safeHead Nothing = Nothing
safeHead (Just (x : xs)) = Just x

字符串
我们还可以通过以下方式简化实现:

import Data.Maybe (listToMaybe)

safeHead :: Maybe [a] -> Maybe a
safeHead = (>>= listToMaybe)

9ceoxa92

9ceoxa923#

safeHead函数所关注的安全问题是接收一个空列表作为输入,无论它是否被 Package 为Just值。参数类型仍然是[a];只有返回类型从a提升到Maybe a

safeHead :: [a] -> Maybe a
safeHead [] = Nothing  -- instead of an error
safeHead (x:_) = Just x

字符串
Maybe [a]值上使用safeHead(例如,由safeTail函数返回)是通过使用MaybeMonad示例完成的。

safeTail :: [a] -> Maybe [a]
safeTail [] = Nothing
safeTail (_:xs) = Just xs


然后

> safeTail [] >>= safeHead -- Nothing >>= safeHead
Nothing
> safeTail [1] >>= safeHead  -- Just [] >>= safeHead
Nothing
> safeTail [1,2] >>= safeHead -- Just [2] >>= safeHead
Just 2

相关问题