Haskell Commutative Function

I want to write a function in haskell that would not mind in which order I give it its argument, for example, I want to combine these two functions

reproduce1 :: Male -> Female -> Child reproduce2 :: Female -> Male -> Child 

single function "multiply".

+7
source share
4 answers

You can do this using a class with several parameters.

 {-# LANGUAGE MultiParamTypeClasses #-} class Reproduce xy where reproduce :: x -> y -> Child instance Reproduce Male Female where reproduce = reproduce1 instance Reproduce Female Male where reproduce = reproduce2 

However, I wonder why you would like to do this.

+12
source

Perhaps you want to pack your arguments into a data type and use records (see "Labeled Fields") instead?

  data Args = A { m :: Male , f :: Female} reproduce :: Args -> Child 

However, I share @hammar's curiosity.

+5
source

I was thinking of something similar, which raises an exception if both adults are of the same gender:

 module Main where main = putStrLn (reproduce (Male "a") (Female "b")) type Child = String data Adult = Male String | Female String deriving (Show) reproduce :: Adult -> Adult -> Child reproduce (Male a) (Female b) = a ++ "+" ++ b reproduce (Female a) (Male b) = b ++ "+" ++ a 
+2
source

I strongly recommend setting the order, say, first Male and then Female, or create a “type of marriage”, as in ShiDoSi's solution.

However, check out the “Session Types and Duality” section, page 12 in the article “Fun with Type Functions” - I think this is a good example where you need types associated in symmetrical pairs of male and female.

+1
source

All Articles