尝试实现 Data.Either

发布于 2024-11-30 13:21:28 字数 1837 浏览 1 评论 0原文

为了帮助我学习 Applicative Functor 和 Functor,我认为了解如何使用类型类 FunctorApplicative 实现 Either 会很有趣。显然,我可以继续阅读代码,但我发现自己尝试和实现一些东西以更好地理解事物更有用。

仅供参考,我正在尝试实现本演示文稿结果的 Haskell 版本 http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html

无论如何,这就是我所拥有的到目前为止,

 data Validation a b = Success a | Failure b deriving (Show, Eq)

 instance Functor (Validation a) where
     fmap f (Failure x) = Failure x
     fmap f (Success x) = Success (f x)

但是每当我尝试使用 ghci 运行它时,我都会收到以下错误消息: -

[1 of 1] Compiling Main             ( t.hs, interpreted )

t.hs:5:35:
    Couldn't match type `b' with `a1'
      `b' is a rigid type variable bound by
          the type signature for
            fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
          at t.hs:4:5
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    Expected type: a
      Actual type: b
    In the return type of a call of `f'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success (f x)

t.hs:5:37:
    Couldn't match type `a' with `a1'
      `a' is a rigid type variable bound by
          the instance declaration at t.hs:3:30
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    In the first argument of `f', namely `x'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success

我不太确定这是为什么,有人可以帮忙吗?

To help me learn Applicative Functors and Functors I thought it would be good fun to see how Either is implemented with the typeclasses Functor and Applicative. Obviously I could just go ahead and read the code but I find it more useful to try and implement things myself to get a better understanding of things.

FYI I'm trying to implement the Haskell version of the results of this presentation http://applicative-errors-scala.googlecode.com/svn/artifacts/0.6/chunk-html/index.html

Anyway, this is what I have so far

 data Validation a b = Success a | Failure b deriving (Show, Eq)

 instance Functor (Validation a) where
     fmap f (Failure x) = Failure x
     fmap f (Success x) = Success (f x)

But whenever I try to run this with ghci I just get the following error message: -

[1 of 1] Compiling Main             ( t.hs, interpreted )

t.hs:5:35:
    Couldn't match type `b' with `a1'
      `b' is a rigid type variable bound by
          the type signature for
            fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
          at t.hs:4:5
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    Expected type: a
      Actual type: b
    In the return type of a call of `f'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success (f x)

t.hs:5:37:
    Couldn't match type `a' with `a1'
      `a' is a rigid type variable bound by
          the instance declaration at t.hs:3:30
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    In the first argument of `f', namely `x'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success

I'm not really sure why this is, can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蔚蓝源自深海 2024-12-07 13:21:28

您正在尝试使 Functor 实例在 Success 部分上工作,这是正常的事情,但由于类型参数的顺序,它正在被定义改为在 Failure 部分中的类型。

由于您已将其定义为

data Validation a b = Success a | Failure b

instance Functor (Validation a) where
    ...

这意味着您的 fmap 实现应具有类型 (x -> y) ->验证斧->验证 y。但由于第二个类型变量用于 Failure 情况,因此不会进行类型检查。

您希望成功案例的类型变量是最后一个:

data Validation b a = Success a | Failure b

You're trying to make the Functor instance work on the Success part, which is the normal thing to do, but because of the order of your type parameters it is being defined on the type in the Failure part instead.

Since you've defined it as

data Validation a b = Success a | Failure b

instance Functor (Validation a) where
    ...

This means that your implementation of fmap should have the type (x -> y) -> Validation a x -> Validation a y. But since the second type variable is for the Failure case, this does not type check.

You want the type variable for the Success case to be the last one instead:

data Validation b a = Success a | Failure b
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文