哈斯克尔中的应用实现



我有一个类型显示如下:

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)

相关内容

  • 没有找到相关文章

最新更新