简体   繁体   中英

Semigroup with data type that contains function

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 ?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM