作为 Monoid 实例的函数类型
Function Types as Monoid Instances
我有一个看起来像这样的函数
transition :: State -> ([State], [State])
鉴于我的问题的特定领域,我知道如何将两个连续的 transition
函数调用链接在一起,如下所示:
transition `chain` trainsition ... `chain` transition
但是,我想将其表示为 Monoid
并执行与 <>
和 mappend
的链接。不幸的是,我似乎无法使以下或类似的变体起作用:
instance Monoid (State -> ([State], [State])) where
mempty = ...
mappend = ...
返回错误如下:
• Illegal instance declaration for
‘Monoid (State -> ([State], [State]))’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for
‘Monoid (State -> ([State], [State]))’
一般来说,函数如何表示为Monoid
的实例?
Functions are already instances of monoids in a different way。您希望 Haskell 如何决定使用该实例还是您的实例?解决问题的通常方法是声明一个 newtype
包装器,例如
newtype Transition a = Transition { runTransition :: a -> ([a], [a]) }
然后,你可以让你的幺半群实例就好了:
instance Monoid (Transition a) where
mempty = ...
mappend = ...
完成此操作后,您甚至可能会发现 foldMap
很有用。而不是写类似
的东西
runTransition (Transition transition `chain`
Transition transition `chain`
...
Transition transition)
您可以使用foldMap
runTransition (foldMap Transition [transition, transition, ... transition])
我有一个看起来像这样的函数
transition :: State -> ([State], [State])
鉴于我的问题的特定领域,我知道如何将两个连续的 transition
函数调用链接在一起,如下所示:
transition `chain` trainsition ... `chain` transition
但是,我想将其表示为 Monoid
并执行与 <>
和 mappend
的链接。不幸的是,我似乎无法使以下或类似的变体起作用:
instance Monoid (State -> ([State], [State])) where
mempty = ...
mappend = ...
返回错误如下:
• Illegal instance declaration for
‘Monoid (State -> ([State], [State]))’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for
‘Monoid (State -> ([State], [State]))’
一般来说,函数如何表示为Monoid
的实例?
Functions are already instances of monoids in a different way。您希望 Haskell 如何决定使用该实例还是您的实例?解决问题的通常方法是声明一个 newtype
包装器,例如
newtype Transition a = Transition { runTransition :: a -> ([a], [a]) }
然后,你可以让你的幺半群实例就好了:
instance Monoid (Transition a) where
mempty = ...
mappend = ...
完成此操作后,您甚至可能会发现 foldMap
很有用。而不是写类似
runTransition (Transition transition `chain`
Transition transition `chain`
...
Transition transition)
您可以使用foldMap
runTransition (foldMap Transition [transition, transition, ... transition])