编译我的自定义 ZipList 应用程序实例需要什么?
What is needed to get my custom ZipList applicative instance to compile?
这是我的自定义列表 class,用于创建自定义 ZipList class。我想创建一个 ZipList 的应用实例。
import Control.Applicative
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
instance Functor List where
fmap f (Cons x xs) = Cons (f x) (fmap f (Cons (head' xs) (tail' xs)))
fmap _ Nil = Nil
instance Applicative List where
pure x = Cons x Nil
(<*>) fs xs = Cons (head' fs $ head' xs) ((<*>) (tail' fs) (tail' xs))
head' :: List a -> a
head' (Cons a _) = a
tail' :: List a -> List a
tail' (Cons _ l) = l
take' :: Int -> List a -> List a
take' 0 _ = Nil
take' _ Nil = Nil
take' i xs = Cons (head' xs) (take' (i-1) (tail' xs))
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)
(<*>) fs xs = ZipList' (go fs xs)
where go gs ys = Cons (head' gs $ head' ys) (go (tail' gs) (tail' ys))
go Nil _ = Nil
go _ Nil = Nil
我得到的错误是:
chap17/ZipList_applicative.hs:38:30: Couldn't match expected type ‘List (r0 -> b)’ …
with actual type ‘ZipList' (a -> b)’
Relevant bindings include
xs :: ZipList' a
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:12)
fs :: ZipList' (a -> b)
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:9)
(<*>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:3)
In the first argument of ‘go’, namely ‘fs’
In the first argument of ‘ZipList'’, namely ‘(go fs xs)’
chap17/ZipList_applicative.hs:38:33: Couldn't match expected type ‘List r0’ …
with actual type ‘ZipList' a’
Relevant bindings include
xs :: ZipList' a
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:12)
fs :: ZipList' (a -> b)
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:9)
(<*>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:3)
In the second argument of ‘go’, namely ‘xs’
In the first argument of ‘ZipList'’, namely ‘(go fs xs)’
Compilation failed.
它说它需要来自 go 的 List (r0 -> b) 类型,而不是 ZipList'。我不明白为什么,去 returns 列表,而不是 ZipList'...
您的 go
将 ZipList
作为输入,但在 (<*>) fs xs
中 xs
和 fs
是 ZipList'
。你应该打开新类型:
ZipList' fs <*> ZipList' xs = ZipList' (go fs xs)
还有,你的go
是错误的。每当程序评估任一参数中的空列表时,它都会失败并出现运行时错误,因为 go gs ys
案例匹配所有内容,并且无法访问它之后的案例。你应该改为这样做:
go (Cons f fs) (Cons x xs) = Cons (f x) (go fs xs)
go _ _ = Nil
作为一般规则,您应该避免使用 head
、tail
和其他部分函数(即可能抛出异常的函数)。 Cons x xs
上的模式匹配同时绑定了头部和尾部,因此此后的 head
和 tail
没有太大用处。很少有人真正证明使用偏函数是合理的。
这是我的自定义列表 class,用于创建自定义 ZipList class。我想创建一个 ZipList 的应用实例。
import Control.Applicative
data List a =
Nil
| Cons a (List a)
deriving (Eq, Show)
instance Functor List where
fmap f (Cons x xs) = Cons (f x) (fmap f (Cons (head' xs) (tail' xs)))
fmap _ Nil = Nil
instance Applicative List where
pure x = Cons x Nil
(<*>) fs xs = Cons (head' fs $ head' xs) ((<*>) (tail' fs) (tail' xs))
head' :: List a -> a
head' (Cons a _) = a
tail' :: List a -> List a
tail' (Cons _ l) = l
take' :: Int -> List a -> List a
take' 0 _ = Nil
take' _ Nil = Nil
take' i xs = Cons (head' xs) (take' (i-1) (tail' xs))
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)
(<*>) fs xs = ZipList' (go fs xs)
where go gs ys = Cons (head' gs $ head' ys) (go (tail' gs) (tail' ys))
go Nil _ = Nil
go _ Nil = Nil
我得到的错误是:
chap17/ZipList_applicative.hs:38:30: Couldn't match expected type ‘List (r0 -> b)’ …
with actual type ‘ZipList' (a -> b)’
Relevant bindings include
xs :: ZipList' a
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:12)
fs :: ZipList' (a -> b)
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:9)
(<*>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:3)
In the first argument of ‘go’, namely ‘fs’
In the first argument of ‘ZipList'’, namely ‘(go fs xs)’
chap17/ZipList_applicative.hs:38:33: Couldn't match expected type ‘List r0’ …
with actual type ‘ZipList' a’
Relevant bindings include
xs :: ZipList' a
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:12)
fs :: ZipList' (a -> b)
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:9)
(<*>) :: ZipList' (a -> b) -> ZipList' a -> ZipList' b
(bound at /Users/ebs/code/haskell/book/chap17/ZipList_applicative.hs:38:3)
In the second argument of ‘go’, namely ‘xs’
In the first argument of ‘ZipList'’, namely ‘(go fs xs)’
Compilation failed.
它说它需要来自 go 的 List (r0 -> b) 类型,而不是 ZipList'。我不明白为什么,去 returns 列表,而不是 ZipList'...
您的 go
将 ZipList
作为输入,但在 (<*>) fs xs
中 xs
和 fs
是 ZipList'
。你应该打开新类型:
ZipList' fs <*> ZipList' xs = ZipList' (go fs xs)
还有,你的go
是错误的。每当程序评估任一参数中的空列表时,它都会失败并出现运行时错误,因为 go gs ys
案例匹配所有内容,并且无法访问它之后的案例。你应该改为这样做:
go (Cons f fs) (Cons x xs) = Cons (f x) (go fs xs)
go _ _ = Nil
作为一般规则,您应该避免使用 head
、tail
和其他部分函数(即可能抛出异常的函数)。 Cons x xs
上的模式匹配同时绑定了头部和尾部,因此此后的 head
和 tail
没有太大用处。很少有人真正证明使用偏函数是合理的。