How to define infix functions in Haskell?

I would like to define the function as infix, so users do not need to manually surround the function with callbacks to call it. In particular, I am writing a function similar to DSL that takes rank and costume and writes a record to a poker card:

-- pseudocode data PokerCard = PokerCard { rank :: Rank, suit :: Suit } deriving (Eq) of :: Rank -> Suit -> PokerCard r of s = PokerCard { rank = r, suit = s } pokerDeck = [ Ace of Spades, Two of Spades, ... ] 

I believe that of reserved as the syntax for case ... of expressions, so I would have to rename it somehow like of' , .of , +of , etc.

+4
source share
3 answers

It is not possible to define a function with an alphanumeric name as infix. Haskell syntax rules only allow functions with symbolic names or function names surrounded by back windows that will be used by infix - there is no way to change this.

+10
source

Well, you may already know this, but (of course) the / operators may be infix. So you could have r >| s instead of r of s r >| s .

+6
source

Here's a hacky solution with some extra tweaking, but no backlinks! I first posted this on reddit if everything is ok.

I assume you got Enum for Rank .

 data OF = OF ace :: OF -> Suit -> PokerCard ace _ s = PokerCard Ace s -- or point-free two :: OF -> Suit -> PokerCard two _ = PokerCard Two -- or with const three :: OF -> Suit -> PokerCard three = const (PokerCard Three) -- you get the idea! -- the rest in one line: four,five,six,seven,eight,nine,ten,jack,king :: OF -> Suit -> PokerCard [four,five,six,seven,eight,nine,ten,jack,king] = map (const . PokerCard) [Four .. King] -- now you can write pokerDeck = [ ace OF Spades, two OF Spades -- and so on ] 

The OF data type is not strictly necessary, but it prevents obfuscation of the (but very metallic) material, such as ace "Motorhead" Spades . You can still write ace undefined Spades , in my opinion there is no way around it.

If of not a keyword, you could even write of = OF .


There is also a completely evil hack to completely get rid of "of" and use card numbers:

 {-# LANGUAGE FlexibleInstances #-} -- this goes on top of your file instance Num (Rank -> Suit) where fromInteger n = (undefined : map Card[Ace .. King]) !! (fromInteger n) 

Now there are 2 Spades :: Card typechecks (but you need an explicit type!) And this is what you think :-) However, I strongly recommend that you do not do this in serious code; but it looks cool.

+6
source

All Articles