Paul Oskar Mayer
Paul Oskar Mayer

Reputation: 1335

Haskell data of Explanation

I'm looking for a good Explanation for this ´Of` after data Card:

data Suit = Club | Diamond | Spade | Heart deriving (Eq, Show, Ord, Enum)
data Value = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Bobe | Dame | King | Ass deriving (Ord, Eq, Show, Enum)

data Card = Value `Of` Suit
    deriving (Show)  

I didn't make it to google a good Doc or explanation.

Upvotes: 2

Views: 85

Answers (2)

delta
delta

Reputation: 3818

The value constructor is just a function. Check it in ghci.

Prelude> data T = F Int Int | Int `G` Int deriving Show
Prelude> :t F
Int -> Int -> T
Prelude> 1 `F` 2
F 1 2
Prelude> :t G
Int -> Int -> T
Prelude> G 1 2
G 1 2

As it is a function, you can use the infix form.

Maybe it is the infix declaring form is bothering you. It is just another way to express.

type P = (Int, Int)
(#*) :: P -> P -> Int
(a, b) #* (c, d) = a * d - b * c

Upvotes: 2

epsilonhalbe
epsilonhalbe

Reputation: 15949

In haskell any (non operator, non partially aplied) function, i.e. with type signature f :: a -> b -> c, can be used infix - with the use of backtick-syntax, which you surround the function with backticks, e.g.

mod m n = m `mod` n

here the first argument of the function goes to the left hand side of the "operator" and the second one to the right.

For the reverse, if you have an operator + and you want to apply it in prefix notation you simply surround it with (,)

a + b = (+) a b

Coming back to your algebraic data type, writing it in the usual way

data Card = Of Value Suit deriving (...)

If you now load your file or paste your definitions into ghci you can ask the interactive compiler about the types of your expressions.

$ > ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
Prelude> data Suit = Heart |... deriving Show
Prelude> data Value = One |... deriving Show
Prelude> data Card = Of Value Suit deriving Show
Prelude> :t Of
Of :: Value -> Suit -> Card

Which is exactly the type we need to use infix syntax - then we can use it in the following form:

Prelude> One `Of` Heart
Of One Heart

Note: if you want to have a function of more than two parameters you have to give it a name like

:t foldl
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
Prelude> -- an example of a function with 3 parameters
Prelude> 0 `foldl (+)` [1..10]

<interactive>:14:10: parse error on input ‘(’
Prelude> let plus = (+)
Prelude> 0 `foldl plus` [1..10]

<interactive>:16:10: parse error on input ‘plus’

does not work, but this will

Prelude> let sumStartingAt = foldl (+)
Prelude> 0 `sumStartingAt` [1..10]
55

Upvotes: 4

Related Questions