Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to replace parentheses with $?

Tags:

haskell

I have the following function:

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = go (div num 10) (mod num 10 : acc)

Is it possible to replace the parentheses in the otherwise expression with $?

like image 828
softshipper Avatar asked Nov 21 '25 09:11

softshipper


1 Answers

The problem

You can't use $ for that. The purpose of $ is to make function application bind as un-tighly as possible, as opposed to normal function application which binds most tightly,

> :i $
($) :: (a -> b) -> a -> b
infixr 0 $

(some irrelevant stuff removed...)

Here, infixr denotes that the operator is right associative, as opposed to infixl which denotes that the operator is left associative. 0 denotes the precedence of the operator. 0 binds least tightly and 9 binds most tightly.

If we write go $ div num 10 $ mod num 10 : acc, this is interpreted as go (div num 10 (mod num 10 : acc)), i.e: passing mod num 10 : acc as the third argument of div, and the result of applying div as the only argument to go.

Solution: the (&) operator

Instead of using the dollar sign, $, for the left hand side, you can instead use &.

> :i &
(&) :: a -> (a -> b) -> b       -- Defined in `Data.Function'
infixl 1 &

And now we get:

import Data.Function ((&))

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 & go $ mod num 10 : acc

Solution: apply go infix

You could also use go infix:

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 `go` (mod num 10 : acc)

In this case, the parenthesis on the right hand side is needed due to (:) which is also infix and interferes with go.

Which solution to use

In my opinion, if you can use infix application without parenthesizes, do that. In the case of having a parenthesis on any side such as in: div num 10 `go` (mod num 10 : acc), it may still be warranted to use infix. This is mainly due to readability, as the average reader may not be familiar with &. This notation is (probably) not very commonly used, which is why the average reader is not very familiar with it (and so we have a cycle...).

On the usage of $$

I believe Alexey Romanov's operator, $$ is quite neat as well. Unfortunately, it suffers the same problems as & does: lack of familiarity. Hopefully, his operator can be added to Data.Function in due time and perhaps we can expand our toolbox.

like image 110
Centril Avatar answered Nov 24 '25 00:11

Centril



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!