Haskell解包也许保持多态

时间:2018-10-20 06:46:54

标签: haskell maybe unwrap

Haskell初学者再次在这里。如果我想解开Maybe类型并想使其抽象,则可以使用:

fUnwrap :: Maybe a -> a 
fUnwrap (Just n) = n 
fUnwrap Nothing = ???

无论我对Nothing做什么,编译器都会不断地讨价还价,以更具体地说明如何处理Nothing ...你们能帮助我吗?

2 个答案:

答案 0 :(得分:8)

这是合乎逻辑的。编译器显示类型为a的值,但是这里没有可以提供的值,因为a可以是任何值(BoolInt,{{1} },[Int]等。

这不是一个编程问题,更多的是 design 问题:如果它是Maybe Int,您想做什么?这里有一些选项:

  1. 提供一个默认值,因此签名为:

    Nothing
  2. 我们在fUnwrap :: a -> Maybe a -> a fUnwrap _ (Just n) = n fUnwrap d Nothing = d的情况下引发错误(我们既可以省略行,也可以显式地引发错误,尽管在后一种情况下,我们可以指定原因):< / p>

    Nothing
  3. 我们返回fUnwrap :: Maybe a -> a fUnwrap (Just n) = n fUnwrap Nothing = error "Nothing has no value"

    undefined

    undefined :: a是一个对象,如果对其进行评估,则会引发错误。因此,这是fUnwrap :: Maybe a -> a fUnwrap (Just n) = n fUnwrap Nothing = undefined的特例,但是我们“推迟”评估,以便如果不需要该值,就不会出错。

但是我个人认为第一种方法在这里是可取的,因为函数签名没有指定它们会引发错误,因此导致代码可能失败,而没有暗示它可以。

通常将error用作可能“失败”的计算的结果类型:如果计算成功,它将返回Maybe a(结果为Just x),否则返回它返回x

例如,您可以使用Nothing表示法从可能失败的计算链中构造do。例如:

Maybe a

,例如foo :: Int -> Maybe Int foo x = do y <- someComputation x otherComputation y

答案 1 :(得分:3)

这是不可能的,因为您编写了函数。由于该函数是纯函数,因此您不能返回a,因为您唯一的输入是Nothing。

也许Maybe的优点在于您无需“拆开”它。您只能使用fmap函数对包装后的数据进行操作,而在Nothing情况下隐式不执行任何操作。