这来自《 Applicative实现ZipList'
,这类似于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
,因为它也可以在无限列表上使用。
这来自《第一原理》中Haskell书中的练习。练习是为ZipList实施Applicative,类似于Prelude的ZipList。这本书有这个提示检查...
fmap f xs = (pure f) <*> xs
):关键是考虑对Applicative
合法实例fmap f x == (pure f) <*> x
的要求,并认识到列表x
的长度没有上限。