Commutative function in Haskell
I want to write a function in haskel开发者_StackOverflow中文版l which would not mind in what order I provide it its argument, for example, I want to unify these two functions
reproduce1 :: Male -> Female -> Child
reproduce2 :: Female -> Male -> Child
by one function 'reproduce'.
You can do this using a multi-parameter type class.
{-# LANGUAGE MultiParamTypeClasses #-}
class Reproduce x y where
reproduce :: x -> y -> Child
instance Reproduce Male Female where
reproduce = reproduce1
instance Reproduce Female Male where
reproduce = reproduce2
However, I'm curious about why you would want to do this.
Maybe you'd like to package your arguments into a datatype and use records (see "Labelled Fields") instead?
data Args = A { m :: Male , f :: Female}
reproduce :: Args -> Child
However, I share @hammar's curiosity.
I was thinking about something like this, which throws an exception if both adults are of the same sex:
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
I strongly recommend fixing the order, say first Male and then Female, or making a "marriage" datatype as in ShiDoSi's solution.
However, check section "Session types and duality", pg 12 in the paper "Fun with type functions" - I think that is a good example where you need types coupled in symmetric pairs male-female.
精彩评论