Search code examples
functional-programmingelm

Why do we show multiple arguments with arrows and the return type with an arrow?


For example in the Elm basics docs:

(/) : Float -> Float -> Float

This is saying that / is a function which takes a float, and another float and returns a float.

Why wouldn't it be like:

(/) : (Float, Float) -> Float

For example, which seems to be more intiutive.

Is there a special reason for this? This is also how types are annotated in Haskel also.

https://package.elm-lang.org/packages/elm/core/latest/Basics

EDIT: This has been answered, but I also found this in the documentation for Elm: https://guide.elm-lang.org/appendix/function_types.html


Solution

  • In functional programming it's easier to use version which returns other functions so when you see (/) : Float -> Float -> Float it means that you can pass one argument and get the function Float -> Float back. So effectively there is no difference in the result (assuming that you pass both arguments).

    This technique of going from tuple version (uncurried) to functional version (curried) is called currying and is widely used and will become intuitive after practice. I'm not familiar with elm but in Haskell you can easily go from curried version and back:

    f :: a -> (b -> c)     -- (which can also be written as    f :: a -> b -> c )
    g :: (a, b) -> c
    
    f = curry g -- transform argument from tuple to functions
    g = uncurry f -- transform function arguments to tuple
    

    So if you apply the function f to only one argument you get back a function which can be re-used. Check the Haskell wiki for more details. In contrary with function which expect tuple the re-usability will be limited. Check also the Partial application section of the wiki to understand why it's important.

    add2 :: Integer -> Integer -> Integer
    add2 a b = a + b
    
    add5 :: Integer -> Integer
    add5 b = add2 5 b -- add2 is re-used