Function 如何在Haskell中定义中缀函数?

Function 如何在Haskell中定义中缀函数?,function,haskell,infix-notation,Function,Haskell,Infix Notation,我想将一个函数定义为中缀,这样用户就不必手动用倒勾来包围函数来调用它。具体来说,我正在编写一个类似DSL的函数,它接受等级和等级,并构造一个扑克记录: -- pseudocode data PokerCard = PokerCard { rank :: Rank, suit :: Suit } deriving (Eq) of :: Rank -> Suit -> PokerCard r of s = PokerCard { rank = r, suit = s } pokerD

我想将一个函数定义为中缀,这样用户就不必手动用倒勾来包围函数来调用它。具体来说,我正在编写一个类似DSL的函数,它接受等级和等级,并构造一个扑克记录:

-- 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,
  ...
  ]

我相信的
保留为
案例的语法。。。表达式,因此我不得不将其重命名为“
”的
+等。

无法将字母数字名称定义为中缀。Haskell的语法规则只允许使用符号名或用反勾号括起来的函数名作为中缀-这是无法改变的。

您可能已经知道这一点,但是(当然)运算符/can/be中缀。因此,您可以改为使用
r/s
r>|s
这是一个有一些额外输入的黑客解决方案,但没有反勾号!如果可以的话,我先在reddit上发布了这个

我假设您已经为
Rank
导出了
Enum

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
   ]
数据类型的定义并不是严格必需的,但可以防止像
ace“Motorhead”Spades这样的混淆(但非常金属化)。你仍然可以写
ace未定义的黑桃
,我想这是没有办法的

如果
of
不是关键字,您甚至可以编写
of=of


还有一个非常邪恶的黑客完全摆脱了“of”,并使用数字作为卡:

{-# LANGUAGE FlexibleInstances #-} -- this goes on top of your file

instance Num (Rank -> Suit) where
  fromInteger n = (undefined : map Card[Ace .. King]) !! (fromInteger n)

现在
2 Spades::Card
typechecks(但您需要显式类型!),这就是您所认为的:-)然而,我强烈建议您不要在严肃的代码中这样做;但它看起来有点酷。

另请参见:的确,运算符必须是中缀。@dave4420,除非用括号括起来。@sepp2k当然可以,但这在道德上与用倒勾括字母数字标识符是一样的。不能定义前缀符号运算符(除非在使用它的任何地方都用括号括起来),正如不能定义中缀字母数字运算符(除非在使用它的任何地方都用反勾号括起来)。