Reputation: 34071
I have following data type and Semigroup
instance of it:
newtype Combine a b =
Combine { unCombine :: a -> b }
instance (Semigroup b)
=> Semigroup (Combine a b) where
Combine {unCombine=f} <> Combine {unCombine=g} = Combine (f <> g)
What does Combine (f <> g)
mean? I pass the function f
and g
to the binary operator <>
what is the output of it?
To figure out how it works, I try to play a bit in prelude:
Prelude> let f = Combine $ \n -> Sum (n + 1)
Prelude> let g = Combine $ \n -> Sum (n - 1)
Prelude> unCombine (f <> g) $ 0
Sum {getSum = 0}
For me it looks like a function composition f
after g
, but am I not sure, how does exactly work. Could someone tell me, how does it work?
Another example(maybe it does not make sense):
*Exercises Data.Semigroup> data Zoo a b = Zoo (a -> b)
*Exercises Data.Semigroup> x = Zoo (+23)
*Exercises Data.Semigroup> :t x
x :: Num b => Zoo b b
How to use x
?
Upvotes: 2
Views: 114
Reputation: 116139
f <> g
is calling the library instance for functions:
instance Semigroup b => Semigroup (a -> b) where
f <> g = \x -> f x <> g x
So, it is defined pointwise.
Perhaps using generalized newtype deriving would have been better here, since Combine
has exactly the same instance. One might even wonder if Combine
is needed at all.
Upvotes: 4