Why doesn't this dollar sign design work?

Yes, another dollar sign. Sorry ... (I used the search function!)

My professor of functional programming of the course told us that the dollar sign 'kinda adds an opening parenthese and then a closing at the end' (this is very roughly described here more or less in the same way). So

fibs = 0 : 1 : zipWith (+) fibs $ tail fibs

should be equivalent

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

Well, that is not so. The second thing compiles fine, the first gives an error:

jkjj.hs:1:8:
    Couldn't match expected type `[a1] -> [a1]' with actual type `[a0]'
    The first argument of ($) takes one argument,
    but its type `[a0]' has none
    In the expression: 0 : 1 : zipWith (+) fibs $ tail fibs
    In an equation for `fibs':
        fibs = 0 : 1 : zipWith (+) fibs $ tail fibs

fibonacci.hs:1:16:
    Couldn't match expected type `[a0]' with actual type `[a1] -> [a1]'
    In the return type of a call of `zipWith'
    Probable cause: `zipWith' is applied to too few arguments
    In the second argument of `(:)', namely `zipWith (+) fibs'
    In the second argument of `(:)', namely `1 : zipWith (+) fibs'

And of course, since $ is a function, things like:

fibs = 0 : 1 $ zipWith (+) fibs (tail fibs)

will not work, so at least the explanation my professor gave was a simplification. While writing this post, I tried to put the brackets so that the error was the same. I got:

fibs = (0 : 1 : zipWith (+) fibs) $ tail fibs

and

fibs = (0: 1: zipWith (+) fibs) (tail fibers)

( , ). ? b $c d (a b) (c d), b (c d)? , / , . , , ( ), google.

, - !

+3
3

. , : $. : , $, . ghci

>> :i :
data [] a = ... | a : [a]        -- Defined in `GHC.Types`
infixr 5 :

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

infixr , ( a + b + c a + (b + c)), ( = ).

, , - ( ). ,

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibs = 0 : (1 : (zipWith (+) fibs (tail fibs)))

fibs = 0 : 1 : zipWith (+) fibs $ tail fibs

fibs = (0 : (1 : (zipWith (+) fibs))) $ (tail fibs)

, $ , .

+9

, a b $ c d (a b) (c d). , : , , . , $ , .

, . :info GHCi:

ghci> :info $
($) :: (a -> b) -> a -> b   -- Defined in `GHC.Base'
infixr 0 $

. - 0.
( 0 9.)

GHCi : :

ghci> :info :
data [] a = ... | a : [a]   -- Defined in `GHC.Types'
infixr 5 :

So : - , 5. : $, $ .

+7

: ,

a b ! c d $ e f % g h

parens , ..

(a b ! c d) (e f % g h)

, , Haskell: function infix 1.

Where this is not entirely good, you also consider syntax if, caseetc. In particular, and that when your professor’s explanation becomes more useful, lambdas are “greedy” for their right:

   \x -> f $ a + x

means \x -> f (a + x), not (\x -> f) (a + x). But "parens to both sides" still makes sense, you just shouldn't include the lambda arrow:

   \x -> f . g $ a + x

means \x -> (f . g) (a + x), not \x -> f . g (a + x).


1 In principle, you can define a user infix operator with such a low priority as $, but this will be confusing.

+3
source

All Articles