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)]
$ operatorThe $ 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, ...]).
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With