【发布时间】:2019-10-28 15:02:20
【问题描述】:
这来自Haskell from First Principles一书中的一个练习。练习是为ZipList' 实现Applicative,类似于Prelude 的ZipList。这本书有这个提示
检查前奏 对于可以为您提供所需的功能。一开始 与字母
z,另一个与字母r。你在找 从这些函数中获取灵感,不能直接 在使用自定义List类型时重用它们,而不是Prelude提供列表类型。
我猜z开头的函数是zipWith,但我不知道以r开头的函数。
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
zipWith' :: (a -> b -> c) -> List a -> List b -> List c
zipWith' _ Nil _ = Nil
zipWith' _ _ Nil = Nil
zipWith' f (Cons x xs) (Cons y ys) = Cons (f x y) (zipWith' f xs ys)
newtype ZipList' a = ZipList' (List a)
deriving (Eq, Show)
instance Functor ZipList' where
fmap f (ZipList' xs) = ZipList' $ fmap f xs
instance Applicative ZipList' where
pure x = ZipList' $ Cons x Nil
(ZipList' fs) <*> (ZipList' xs) = ZipList' $ zipWith' ($) fs xs
这通过了书中的一个测试用例,但我想知道是否有更好的方法来实现它,因为我没有使用以r 开头的函数。我有一种感觉,这应该是 repeat,因为它也应该适用于无限列表。
【问题讨论】:
-
您的
instance Applicative似乎正在使用您未在此处定义的ZipList'类型? -
@WillemVanOnsem 忘记粘贴了,我更新了问题
-
您的
pure不正确,一旦您弄清楚了正确的实现,您就会看到引用了哪个以r开头的函数。关键是考虑fmap f x == (pure f) <*> x对合法Applicative实例的要求,并认识到列表x的长度没有上限。这应该足以让您弄清楚。 -
@RobinZigmond
pure 1 :: ZipList Int创建了一个无限列表,所以这似乎是我的问题,我正在尝试弄清楚它现在如何满足法律要求。
标签: haskell typeclass applicative algebraic-data-types custom-data-type