Reputation: 1335
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
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
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