Haskell, синтаксические сокращающие скобки - PullRequest
0 голосов
/ 30 апреля 2018

бессмысленный код, который я знаю, но пытаюсь запечатлеть классы типов и т. Д. В моем мозгу.

Вопрос: как мне избавиться от скобок в следующей функции? '$' выдает ошибку, если я использую это где-либо.

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

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Использование синтаксиса записей для ваших типов,

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]
0 голосов
/ 30 апреля 2018

Оператор $

$ является , а не частью синтаксиса 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 не требует скобок, если вы выводите класс single type, поэтому мы можем написать его следующим образом:

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

Кроме того, в объявлении функции вы распаковываете кортежи, но затем вы перепаковываете элементы кортежа обратно в кортеж, который в основном одинаков. Мы можем уменьшить выражение (и уменьшить объем распаковки и повторной упаковки), связавшись с содержимым конструктора XY вместо этого:

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