Function types as monoid instances
I have a function that looks like
transition :: State -> ([State], [State])
Given the specific domain of my problem, I know how to group two sequential function calls transition
, something like this:
transition `chain` trainsition ... `chain` transition
However, I would like to express this as Monoid
and chaining with <>
and mappend
. Unfortunately, I cannot get the following or similar options to work:
instance Monoid (State -> ([State], [State])) where
mempty = ...
mappend = ...
The returned error looks like this:
β’ 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]))β
In general, how can functions be expressed as instances Monoid
?
source to share
Functions are already instances of monoids in a different way . How do you expect Haskell to decide to use this instance or your instance? The usual way to solve your problem is to declare a wrapper newtype
like
newtype Transition a = Transition { runTransition :: a -> ([a], [a]) }
Then you can make your monoid instance just fine:
instance Monoid (Transition a) where
mempty = ...
mappend = ...
After that, you may even find it foldMap
helpful. Instead of writing something like
runTransition (Transition transition `chain`
Transition transition `chain`
...
Transition transition)
you can use foldMap
runTransition (foldMap Transition [transition, transition, ... transition])
source to share