Why can you define a function without parameter in haskell

I have an add function that I use in part to create a new addOne function.

add :: Int -> (Int -> Int)
add x y = x + y

      

addOne can be defined with an explicit parameter

addOne :: Int -> Int
addOne y = add 1 y

      

or without an explicit parameter

addOne :: Int -> Int
addOne = add 1

      

I have four questions:

  • Why can I define a new function without an explicit parameter?
  • Is there a difference between these two definitions?
  • When do I know when I can define a function without a parameter?
  • Which definition is preferable and when?
+3


source to share


2 answers


  • Because it addOne y = add 1 y

    means addOne = \y -> add 1 y

    , but \x -> f x

    always simple f

    . This is called the eta equivalence. So addOne = add 1

    .

  • Not

  • Is always. Functional parameters are just syntactic sugar for lambda:

    add :: Int -> Int -> Int
    add = \x y -> x + y
    
          

    Whether it is possible to completely remove the binding of a variable is another matter.

  • It's always nice to "eta reduce" (that is, remove the rightmost bound variable in the function binding when it matches the function application in the bound expression) when you can, as it avoids typing an extra name.



+5


source


One of the basic concepts of functional programming that you need to learn to use Haskell is that functions are just some kind of value, definitions are just names. This is not like procedural languages, where the sharp distinction between functions and variables and function definitions are completely different from variable definitions.

So the definition of a variable like

addOne :: Int -> Int
addOne = add 1

      

just adds the name of the expression add 1

, so you can refer to it as addOne

. It is identical to a variable declaration. [1] The fact that the value of this variable is a function is almost random from a Haskell perspective.

Your definition add

:



add :: Int -> (Int -> Int)
add x y = x + y

      

is also a variable definition. This is a bit of syntactic sugar that Haskell provides:

add :: Int -> Int -> Int
add = \ x -> \ y -> x + y

      

in theory it's easier to read. But that's just sugar; you will never need this (except see [1] below), as in other languages.

[1]: a terrible limitation of monomorphismalso comes into play here. The idea is this: in the function definition, the RHS will be executed by the computer many times (as many times as you call the function). You probably know about this from other languages. In the definition of monomorphic variables, RHS will be executed at most once, which is also similar to how other languages ​​work. However, a polymorphic variable often ends up like a function definition, with the RHS executed as many times as is available to access the variable. So Haskell dis-allows polymorphic definitions if you don't have a signature of the polymorphic type (so you say "I know what I'm doing, allow this variable to be polymorphic"), or you have arguments on the left side (so that "looks like" for example "RHS must run many times)."

+4


source







All Articles