我有一个类型显示如下:
newtype WarningAccumulator w a = WarningAccumulator (a,[w])
deriving (Show,Eq)
然后我有一个函子和应用程序,如下所示:
instance Functor (WarningAccumulator w) where
fmap :: (a -> b) -> WarningAccumulator w a -> WarningAccumulator w b
fmap f (WarningAccumulator (value, list)) = WarningAccumulator(f value, list)
instance Applicative (WarningAccumulator w) where
pure :: a -> WarningAccumulator w a
pure a = WarningAccumulator (a,[])
(<*>) :: WarningAccumulator w (a -> b) -> WarningAccumulator w a -> WarningAccumulator w b
(<*>) (WarningAccumulator (empty, f)) (WarningAccumulator (value, list)) =
WarningAccumulator (f value, list)
现在它给了我一个错误:
The function ‘f’ is applied to one value argument,
but its type ‘[w]’ has none
In the expression: f value
In the first argument of ‘WarningAccumulator’, namely
‘(f value, list)’
我不明白。你能向我解释一下,然后帮我解决这个问题吗?
f
的类型为[w]
,这不是函数的类型,因此不能value
应用于它。你可能的意思是:
-- (empty, f) changed to (f, empty)
(<*>) (WarningAccumulator (f, empty)) (WarningAccumulator (value, list)) =
WarningAccumulator (f value, list)
但是,这种Applicative
是不合法的:它不符合交换法
u <*> pure y = pure ($ y) <*> u
例如:
u :: WarningAccumulator String (Int -> Int)
u = WarningAccumulator ((+1), ["warning"])
y :: Int
y = 2
u <*> pure y == WarningAccumulator (3, [])
而pure ($ y) <*> u == WarningAccumulator (3, ["warning"])
.
您可能希望连接警告,而不是丢弃您命名empty
的内容(可能不为空):
(<*>) (WarningAccumulator (f, xs)) (WarningAccumulator (value, ys)) =
WarningAccumulator (f value, xs <> ys)