我知道无意义的代码,但试图在我的大脑中印上类词类等。
问题:如何摆脱以下功能中的括号?如果我在任何地方使用它,'$'会抛出错误。
data Vector = Vector XY XY deriving (Show)
data XY = XY (Float , Float) deriving (Show)
vector (Vector (XY (x1,y1)) (XY(x2,y2))) = [(x1,y1),(x2,y2)]
答案 0 :(得分:4)
$
运算符 $
不是 Haskell语法的一部分。它是内置的运算符 ($) :: (a -> b) -> a -> b
,运算符定义为inxfixr 0
,具有实现:
($) :: (a -> b) -> a -> b
($) f x = f x
因此,它将函数f
和值x
作为输入,并且基本上返回应用于f
的{{1}}。由于它具有优先级x
,这意味着它绑定非常低,因此如果你写
0
你真的写道:
f . g $ x + 2
这是一个详细的形式:
($) ((.) f g) ((+) x 2)
或:
((.) f g) ((+) x 2)
因此它可以用作“技巧”来强制Haskell自己添加括号。由于它是一个运算符,而不是语法的一部分,因此它不适用于其他位置,如类型签名,模式,派生子句。
当然,操作员也有其他目的。例如,我们可以在其他更高阶函数中使用它(例如(f . g) (x + 2)
,其中包含函数列表zipWith ($)
和值列表[f1, f2, ...]
并返回列表[x1, x2, ...]
)
然而,我们可以最小化括号的数量。例如[f1 x1, f2 x2, ...]
子句不需要括号,如果你只派生一个单个类型类,那么我们可以这样写:
deriving
此外,在函数声明中,您解压缩元组,但是将元组元素重新替换为基本相同的元组中的元组元素。我们可以通过绑定data Vector = Vector XY XY deriving Show
data XY = XY (Float , Float) deriving Show
构造函数的内容来减少表达式(并减少解包和重新打包的数量):
XY
答案 1 :(得分:2)
使用类型的记录语法
data XY = XY {xy :: (Float, Float)} deriving (Show)
data Vector = Vector {v1 :: XY, v2 :: XY} deriving (Show)
你可以在没有明确模式匹配的情况下编写vector
:
vector :: Vector -> [(Float, Float)]
vector v = map xy [v1 v, v2 v]