Haskell ZipList 适用 [英] Haskell ZipList Applicative

查看:23
本文介绍了Haskell ZipList 适用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的 ZipList 编写一个 Applicative 实例,但得到了一些令人困惑的结果.

I'm trying to write an instance of Applicative for my ZipList and I'm getting some confusing results.

data List a =
    Nil
  | Cons a (List a)
  deriving (Eq, Show)

newtype ZipList' a =
  ZipList' (List a)
  deriving (Eq, Show)

instance Applicative ZipList' where
  pure = ZipList' . flip Cons Nil
  (<*>) (ZipList' Nil) _ = ZipList' Nil
  (<*>) _ (ZipList' Nil) = ZipList' Nil
  (<*>) (ZipList' (Cons f fs)) (ZipList' (Cons x xs)) =
    ZipList' $ Cons (f x) (fs <*> xs)

对于长度为 1 或 2 的 ZipList,它按预期工作:

It works as expected for ZipLists of length 1 or 2:

> ZipList' (Cons (*2) (Cons (+9) Nil)) <*> ZipList' (Cons 5 (Cons 9 Nil))
ZipList' (Cons 10 (Cons 18 Nil))

但是当我达到 3+ 时,我得到了一些奇怪的结果:

But when I go to 3+, I get some odd results:

> ZipList' (Cons (*2) (Cons (+99) (Cons (+4) Nil))) <*> ZipList' (Cons 5 (Cons 9 (Cons 1 Nil)))
ZipList' (Cons 10 (Cons 108 (Cons 100 (Cons 13 (Cons 5 Nil)))))

结果应该是 10、108、5 的 ZipList——但不知何故 100 和 13 正在破坏派对.

The result should be a ZipList of 10, 108, 5 -- but somehow 100 and 13 are crashing the party.

所以我尝试从实例中提取我的函数,以便我可以检查 Haskell 推断的类型:

So I tried pulling my function out of the instance so that I could inspect the type that Haskell infers:

(<**>) (ZipList' Nil) _ = ZipList' Nil
(<**>) _ (ZipList' Nil) = ZipList' Nil
(<**>) (ZipList' (Cons f fs)) (ZipList' (Cons x xs)) =
  ZipList' $ Cons (f x) (fs <**> xs)

但它不会编译!

17-applicative/list.hs:94:26: error:
    • Couldn't match expected type ‘ZipList' (a0 -> b0)’
                  with actual type ‘List (a -> b)’
    • In the first argument of ‘(<**>)’, namely ‘fs’
      In the second argument of ‘Cons’, namely ‘(fs <**> xs)’
      In the second argument of ‘($)’, namely ‘Cons (f x) (fs <**> xs)’
    • Relevant bindings include
        xs :: List a (bound at 17-applicative/list.hs:93:49)
        x :: a (bound at 17-applicative/list.hs:93:47)
        fs :: List (a -> b) (bound at 17-applicative/list.hs:93:26)
        f :: a -> b (bound at 17-applicative/list.hs:93:24)
        (<**>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
          (bound at 17-applicative/list.hs:91:1)

错误告诉我,我正在尝试传递一个我可以看到的 ZipList 列表.但是我的 Applicative 实例是如何编译的?

The error tells me that I'm trying to pass a List where a ZipList is expected, which I can see. But how then did my Applicative instance even compile?

推荐答案

问题是 <*>ZipList' $ Cons (fx) (fs <*>; xs).

这不是ZipList'<*>,而是List的.

试试ZipList' $ Cons (f x) (case ZipList' fs <*> ZipList' xs of ZipList ys -> ys)`

这篇关于Haskell ZipList 适用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆