Haskell ZipList 应用程序
Haskell ZipList Applicative
我正在尝试为我的 ZipList 编写一个 Applicative 实例,但我得到了一些令人困惑的结果。
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,它按预期工作:
> ZipList' (Cons (*2) (Cons (+9) Nil)) <*> ZipList' (Cons 5 (Cons 9 Nil))
ZipList' (Cons 10 (Cons 18 Nil))
但是当我转到 3+ 时,我得到了一些奇怪的结果:
> 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 使聚会崩溃。
所以我尝试将我的函数从实例中拉出来,以便我可以检查 Haskell 推断的类型:
(<**>) (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 实例是如何编译的呢?
问题是 ZipList' $ Cons (f x) (fs <*> xs)
中的 <*>
。
不是 ZipList'
的 <*>
,是 List
的。
尝试ZipList' $ Cons (f x) (case ZipList' fs <*> ZipList' xs of ZipList ys -> ys)
`
我正在尝试为我的 ZipList 编写一个 Applicative 实例,但我得到了一些令人困惑的结果。
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,它按预期工作:
> ZipList' (Cons (*2) (Cons (+9) Nil)) <*> ZipList' (Cons 5 (Cons 9 Nil))
ZipList' (Cons 10 (Cons 18 Nil))
但是当我转到 3+ 时,我得到了一些奇怪的结果:
> 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 使聚会崩溃。
所以我尝试将我的函数从实例中拉出来,以便我可以检查 Haskell 推断的类型:
(<**>) (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 实例是如何编译的呢?
问题是 ZipList' $ Cons (f x) (fs <*> xs)
中的 <*>
。
不是 ZipList'
的 <*>
,是 List
的。
尝试ZipList' $ Cons (f x) (case ZipList' fs <*> ZipList' xs of ZipList ys -> ys)
`