【问题标题】:How to implement a instance of Functor for a self defined data in haskell如何在haskell中为自定义数据实现Functor实例
【发布时间】:2018-01-07 05:42:56
【问题描述】:

我是 Haskell 的初学者。现在我尝试定义如下数据:

data Unsure a = Sure a |Error [Char]
 deriving (Show)

然后尝试像这样实现 Functor:

instance Functor Unsure where
    fmap f (Sure x) = Sure (f x)
    fmap f (Error e) = Error e

在我看来,一旦我实现了 Functor for Unsure,fmap 应该可以工作。所以我可以使用 fmap 来做类似的事情:

fmap (+3) (+100) Sure 1

结果应该是 Sure 104 ,实际上我得到了错误

• 约束中的非类型变量参数:Num(不确定 a) (使用 FlexibleContexts 来允许这样做) • 检查推断类型时 它 :: forall a. (Num (Unsure a), Num a) => 不确定

有什么建议吗?

【问题讨论】:

  • 为什么你认为这应该有效?
  • 我弄错了,现在当我输入 fmap (+3) Sure 1 时,它显示 Sure 4。
  • 其实我想要一个通用的方法来取消 Unsure 然后我可以做一些事情比如 fmap (==) 100 (Sure 100)。
  • 这是一个有趣的错误!如果你写了fmap (+3) (Sure 1),事情就会奏效,fmap (+3) (+100) 1 也会奏效(出于微妙的原因)。如果您写了fmap (+3) Sure 1,您可能会收到一条合理的错误消息,但fmap (+3) (+100) Sure 1 是一个完美的风暴,它会创建一个令人讨厌的错误消息。
  • 你已经可以这样做了,你只需要把100放在括号内:fmap (==100) (Sure 100) Sure True。

标签: haskell functor


【解决方案1】:

您可能打算写fmap ((+3) . (+100)) (Sure 1)fmap (+3) $ fmap (+100) (Sure 1)

【讨论】:

    【解决方案2】:

    fmap 是一个类型为 fmap :: Functor f => (a -> b) -> f a -> f b 的函数。

    换句话说,函数 fmap 接受 两个 参数: 第一个参数是从ab 类型的函数。 第二个参数是 a 类型的 Functor 的值。结果是一个 b 类型的 Functor。

    在您的示例中,您编写:fmap (+3) (+100) Sure 1。在这个例子中 fmap四个 参数: 第一个是(+3),第二个是(+100),第三个id是Sure,第四个是1

    正如@Brian Olivier 所写,从(+3)(+100) 中提出一个论点 您可以将它们与 (.) 运算符结合起来,并将此表达式放入括号中。然后,这为您提供了 fmap 的第一个参数。

    然后你必须把Sure 1放在括号里 获取 fmap 的第二个参数。

    所以你必须一起写fmap ((+3) . (+100)) (Sure 1)

    【讨论】:

      【解决方案3】:

      除了其他人所说的,如果您添加使用DeriveFunctor 语言扩展(例如通过{-# LANGUAGE DeriveFunctor #-} pragma),您可以派生函子:

      data Unsure a = Sure a |Error [Char]
        deriving (Show, Functor)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-03
        • 1970-01-01
        • 2012-05-04
        • 1970-01-01
        • 1970-01-01
        • 2019-06-30
        相关资源
        最近更新 更多