Function 如何在Haskell中定义中缀函数?
我想将一个函数定义为中缀,这样用户就不必手动用倒勾来包围函数来调用它。具体来说,我正在编写一个类似DSL的函数,它接受等级和等级,并构造一个扑克记录: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
-- 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当然可以,但这在道德上与用倒勾括字母数字标识符是一样的。不能定义前缀符号运算符(除非在使用它的任何地方都用括号括起来),正如不能定义中缀字母数字运算符(除非在使用它的任何地方都用反勾号括起来)。