【问题标题】:Haskell, syntactic reducing bracketsHaskell,语法减少括号
【发布时间】:2018-04-30 10:36:17
【问题描述】:

我知道一些无意义的代码,但试图在我的脑海中留下类型类等等。

问题:如何去掉下面函数中的括号?如果我在任何地方使用它,'$' 会引发错误。

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)]

【问题讨论】:

  • 你只能在表达式中使用$,因为$并不是真正的Haskell语法。它是一个运算符,基本上是一种“欺骗” Haskell 添加括号本身的方法。
  • 我还看不出你想在哪里摆脱它。您可以与XY 的内容进行模式匹配,而不是解包元组(这可以更有效),您还可以删除deriving 的括号,因为您只派生自一个类型类,并且您可以定义一个pattern.
  • 除非您打算在 XY 类型中添加一些实例(在这种情况下,newtypedata 更合适),您可以将 XY 设为 type 同义词并为自己节省一些括号 - vector (Vector (x1,y1) (x2,y2)) = [(x1,y1),(x2,y2)].
  • 清除!感谢您的解释。更进一步!
  • 您的代码中没有任何类型类; VectorXY 只是类型

标签: haskell brackets reduction


【解决方案1】:

$ 运算符

$ 不是 Haskell 语法的一部分。它是一个内置的运算符 ($) :: (a -> b) -> a -> b,运算符被定义为inxfixr 0 并实现:

($) :: (a -> b) -> a -> b
($) f x = f x

所以它将函数f 和值x 作为输入,并且基本上返回f 应用于x。由于它具有优先级0,这意味着它的绑定非常低,因此如果你写

f . g $ x + 2

你真的写了:

($) ((.) f g) ((+) x 2)

这是以下的详细形式:

((.) f g) ((+) x 2)

或:

(f . g) (x + 2)

所以它可以用作“技巧”来强制 Haskell 自己添加括号。由于它是一个运算符,而不是语法的一部分,因此它不适用于其他位置,例如类型签名、模式、派生子句。

当然,运算符也有其他用途。例如,我们可以在其他高阶函数中使用它(例如 zipWith ($),它接受函数列表 [f1, f2, ...] 和值列表 [x1, x2, ...] 并返回列表 [f1 x1, f2 x2, ...])。

减少括号的数量

但是,我们可以尽量减少括号的数量。例如,deriving 子句 not 如果您只派生 single 类型类,则不需要括号,所以我们可以这样写:

data Vector = Vector XY XY deriving Show
data XY = XY (Float , Float) deriving Show

此外,在函数声明中,您unpack 元组,然后您replack 将元组元素放回一个基本相同的元组中。我们可以通过绑定XY构造函数的内容来减少表达式(并减少解包和重新打包的数量):

vector (Vector (XY xy1) (XY xy2)) = [xy1, xy2]

【讨论】:

  • 你能不能提一下 $ 只是函数应用程序(+ hacks,我们可能不应该在这里提到)?对于初学者(这里最有可能的观众)可能并不明显。
【解决方案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]

【讨论】:

  • 有用的评论。 xy 上的映射我不太了解,但那是我对 Haskell 的新手
  • 相当于[xy (v1 v), xy (v2 v)];它只是将xy 应用于第二个参数中的每个值。
猜你喜欢
  • 2014-12-12
  • 1970-01-01
  • 2013-08-24
  • 2019-08-11
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
相关资源
最近更新 更多