Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell, syntactic reducing brackets

Nonsensical code I know, but trying to imprint typeclasses and so on in my brain.

Question: how do I get rid of the brackets in the following function? '$' throws an error if I use that anywhere.

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)]
like image 349
Madderote Avatar asked Jan 29 '26 00:01

Madderote


1 Answers

The $ operator

The $ is not part of the Haskell syntax. It is a builtin operator ($) :: (a -> b) -> a -> b and the operator is defined as an inxfixr 0 with implementation:

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

So it takes as input a function f and a value x, and basically returns f applied to x. Since it has precedence 0, that means that it binds very low, and hence if you write

f . g $ x + 2

you actually write:

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

which is a verbose form of:

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

or:

(f . g) (x + 2)

So it can be used as a "trick" to force Haskell to add brackets itself. Since it is an operator, and not part of the syntax, it does not work at other locations like type signatures, patterns, deriving clauses.

The operator serves other purposes as well of course. For example we can use it in other higher-order functions (like zipWith ($) that takes a list of functions [f1, f2, ...] and a list of values [x1, x2, ...] and returns a list [f1 x1, f2 x2, ...]).

Minizing the number of brackets

We can however minimize the amount of brackets. The deriving clause for example does not need brackets if you only derive a single type class, so we can write it like:

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

Furthermore in the function declaration, you unpack the tuples, but then you replack the tuple elements back in a tuple that is basically the same. We can reduce the expression (and reduce the amount of unpacking and repacking) by binding with the content of the XY constructor instead:

vector (Vector (XY xy1) (XY xy2)) = [xy1, xy2]
like image 103
Willem Van Onsem Avatar answered Jan 30 '26 20:01

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!