Why can you define function without parameter in haskell - haskell

I have function add which I apply partially to create a new function addOne.
add :: Int -> (Int -> Int)
add x y = x + y
addOne can be defined with explicit parameter
addOne :: Int -> Int
addOne y = add 1 y
or without explict parameter
addOne :: Int -> Int
addOne = add 1
I have four questions:
Why can I define the new function without explicit parameter?
Is there any difference between these two definitions?
When do I know when I can define function without a parameter?
Which definition is preferred and when?

Because addOne y = add 1 y means addOne = \y -> add 1 y, and \x -> f x is always just f. This is called eta equivalence. So addOne = add 1.
No
Always. Function parameters are just syntactic sugar for lambdas:
add :: Int -> Int -> Int
add = \x y -> x + y
Whether you can remove the variable binding completely is a different matter.
It's always nice to "eta reduce" (that is, remove the rightmost bound variable in a function binding when it matches a function application in the bound expression) when you can, as it avoids introducing a superfluous name.

One of the basic concepts in functional programming that you'll need to learn to use Haskell is that functions are just a kind of value, definitions just name things. It's not like procedural languages where there's a sharp distinction made between functions and variables and function definitions are completely different from variable definitions.
So a variable definition like
addOne :: Int -> Int
addOne = add 1
is just adding a name for the expression add 1, so you can refer to it as addOne. It's identical to a variable declaration.[1] The fact that the value of that variable is a function is almost incidental, from Haskell's perspective.
Your add definition:
add :: Int -> (Int -> Int)
add x y = x + y
is also a variable definition. It's a bit of syntax sugar Haskell provides for:
add :: Int -> Int -> Int
add = \ x -> \ y -> x + y
on the theory that it's easier to read. But it's still just sugar; you never need it (except see [1] below) like you would in other languages.
[1]: The dreaded monomorphism restriction also comes into play here. The idea is just: in a function definition, the RHS will be executed by the computer many times (as many times as you call the function). You are probably aware of this from other languages. In a monomorphic variable definition, the RHS will be executed at most once, which is also similar to how other languages work. However, a polymorphic variable often ends up acting like a function definition, with the RHS being executed as many times as the value of the variable is accessed. So Haskell dis-allows polymorphic definitions unless you have a polymorphic type signature (so you say "I know what I'm doing, allow this variable to be polymorphic") or you have arguments on the left-hand side (so it "looks like" the RHS should be executed many times).

Related

Type inference in where clauses

If I write
foo :: [Int]
foo = iterate (\x -> _) 0
GHC happily tells me that x is an Int and that the hole should be another Int. However, if I rewrite it to
foo' :: [Int]
foo' = iterate next 0
where next x = _
it has no idea what the type of x, nor the hole, is. The same happens if I use let.
Is there any way to recover type inference in where bindings, other than manually adding type signatures?
Not really. This behavior is by design and is inherited from the theoretical Hindley-Milner type system that formed the initial inspiration for Haskell's type system. (The behavior is known as "let-polymoprhism" and is arguably the most critical feature of the H-M system.)
Roughly speaking, lambdas are typed "top-down": the expression (\x -> _) is first assigned the type Int -> Int when type-checking the containing expression (specifically, when type-checking iterate's arguments), and this type is then used to infer the type of x :: Int and of the hole _ :: Int.
In contrast, let and where-bound variables are typed "bottom-up". The type of next x = _ is inferred first, independently of its use in the main expression, and once that type has been determined, it's checked against its use in the expression iterate next 0. In this case, the expression next x = _ is inferred to have the rather useless type p -> t. Then, that type is checked against its use in the expression iterate next 0 which specializes it to Int -> Int (by taking p ~ Int and t ~ Int) and successfully type-checks.
In languages/type-systems without this distinction (and ignoring recursive bindings), a where clause is just syntactic sugar for a lambda binding and application:
foo = expr1 where baz = bazdefn ==> foo = (\baz -> expr1) bazdefn
so one thing you could do is "desugar" the where clause to the "equivalent" lambda binding:
foo' :: [Int]
foo' = (\next -> iterate next 0) (\x -> _)
This syntax is physically repulsive, sure, but it works. Because of the top-down typing of lambdas, both x and the hole are typed as Int.

Implicit, static type cast (coercion) in Haskell

Problem
Consider the following design problem in Haskell. I have a simple, symbolic EDSL in which I want to express variables and general expressions (multivariate polynomials) such as x^2 * y + 2*z + 1. In addition, I want to express certain symbolic equations over expressions, say x^2 + 1 = 1, as well as definitions, like x := 2*y - 2.
The goal is to:
Have a separate type for variables and general expressions - certain
functions might be applied to variables and not complex expressions.
For instance, a definition operator := might be of type
(:=) :: Variable -> Expression -> Definition and it should not
be possible to pass a complex expression as its left-hand side
parameter (though it should be possible to pass a variable as its
right-hand side parameter, without explicit casting).
Have expressions an instance of Num, so that it's possible to
promote integer literals to expressions and use a convenient
notation for common algebraic operations like addition or
multiplication without introducing some auxiliary wrapper operators.
In other words, I would like to have an implicit and static type cast (coercion) of variables to expressions. Now, I know that as such, there are no implicit type casts in Haskell. Nevertheless, certain object-oriented programming concepts (simple inheritance, in this case) are expressible in Haskell's type system, either with or without language extensions. How could I satisfy both above points while keeping a lightweight syntax? Is it even possible?
Discussion
It is clear that the main problem here is Num's type restriction, e.g.
(+) :: Num a => a -> a -> a
In principle, it's possible to write a single (generalised) algebraic data type for both variables and expressions. Then, one could write := in such a way, that the left-hand side expression is discriminated and only a variable constructor is accepted, with a run-time error otherwise. That's however not a clean, static (i.e. compile-time) solution...
Example
Ideally, I would like to achieve a lightweight syntax such as
computation = do
x <- variable
t <- variable
t |:=| x^2 - 1
solve (t |==| 0)
In particular, I want to forbid notation like
t + 1 |:=| x^2 - 1 since := should give a definition of a variable and not an entire left-hand side expression.
To leverage polymorphism rather than subtyping (because that's all you have in Haskell), don't think "a variable is an expression", but "both variables and expressions have some operations in common". Those operations can be put in a type class:
class HasVar e where fromVar :: Variable -> e
instance HasVar Variable where fromVar = id
instance HasVar Expression where ...
Then, rather than casting things, make things polymorphic. If you have v :: forall e. HasVar e => e, it can be used both as an expression and as a variable.
example :: (forall e. HasVar e => e) -> Definition
example v = (v := v) -- v can be used as both Variable and Expression
where
(:=) :: Variable -> Expression -> Definition
Skeleton to make the code below typecheck: https://gist.github.com/Lysxia/da30abac357deb7981412f1faf0d2103
computation :: Solver ()
computation = do
V x <- variable
V t <- variable
t |:=| x^2 - 1
solve (t |==| 0)

A Haskell function is higher order if and only if its type has more than one arrow?

A professor teaching a class I am attending claimed the following.
A higher-order function could have only one arrow when checking its type.
I don't agree with this statement I tried to prove it is wrong. I tried to set up some function but then I found that my functions probably aren't higher-order functions. Here is what I have:
f x y z = x + y + z
f :: a -> a-> a -> a
g = f 3
g :: a -> a -> a
h = g 5
h :: a -> a
At the end of the day, I think my proof was wrong, but I am still not convinced that higher-order functions can only have more than one arrow when checking the type.
So, is there any resource or perhaps someone could prove that higher-order function may have only one arrow?
Strictly speaking, the statement is correct. This is because the usual definition of the term "higher-order function", taken here from Wikipedia, is a function that does one or both of the following:
takes a function as an argument, or
returns a function as its result
It is clear then that no function with a single arrow in its type signature can be a higher-order function, because in a signature a -> b, there is no "room" to create something of the form x -> y on either side of an arrow - there simply aren't enough arrows.
(This argument actually has a significant flaw, which you may have spotted, and which I'll address below. But it's probably true "in spirit" for what your professor meant.)
The converse is also, strictly speaking, true in Haskell - although not in most other languages. The distinguishing feature of Haskell here is that functions are curried. For example, a function like (+), whose signature is:
a -> a -> a
(with a Num a constraint that I'll ignore because it could just confuse the issue if we're supposed to be counting "arrows"), is usually thought of as being a function of two arguments: it takes 2 as and produces another a. In most languages, which all of course have an analagous function/operator, this would never be described as a higher-order function. But in Haskell, because functions are curried, the above signature is really just a shorthand for the parenthesised version:
a -> (a -> a)
which clearly is a higher-order function. It takes an a and produces a function of type a -> a. (Recall, from above, that returning a function is one of the things that characterises a HOF.) In Haskell, as I said, these two signatures are one and the same thing. (+) really is a higher-order function - we just often don't notice that because we intend to feed it two arguments, by which we really mean to feed it one argument, result in a function, then feed that function the second argument. Thanks to Haskell's convenient, parenthesis-free, syntax for applying functions to arguments, there isn't really any distinction. (This again contrasts from non-functional languages: the addition "function" there always takes exactly 2 arguments, and only giving it one will usually be an error. If the language has first-class functions, you can indeed define the curried form, for example this in Python:
def curried_add(x):
return lambda y: x + y
but this is clearly a different function from the straightforward function of two arguments that you would normally use, and usually less convenient to apply because you need to call it as curried_add(x)(y) rather than just say add(x,y).
So, if we take currying into account, the statement of your professor is strictly true.
Well, with the following exception, which I alluded to above. I've been assuming that something with a signature of the form
a -> b
is not a HOF*. That of course doesn't apply if a or b is a function. Often, that function's type will include an arrow, and we're tacitly assuming here that neither a or b contains arrows. Well, Haskell has type synonyms, so we could easily define, say:
type MyFunctionType = Int -> Int
and then a function with signature MyFunctionType -> a or a -> MyFunctionType is most certainly a HOF, even though it doesn't "look like one" from just a glance at the signature.
*To be clear here,a and b refer to specific types which are as yet unspecified - I am not referring to an actual signature a -> b which would mean a polymorphic function that applies to any types a and b, which would not necessarily be functions.
Your functions are higher order. Indeed, take for example your function:
f :: a -> a -> a -> a
f x y z = x + y + z
This is a less verbose form of:
f :: a -> (a -> (a -> a))
So it is a function that takes an a and returns a function. A higher order function is a function that (a) takes a function as parameter, or (b) returns a function. Both can be true at the same time. Here your function f returns a function.
A function thus always has type a -> b with a the input type, and b the return type. In case a has an arrow (like (c -> d) -> b), then it is a higher order function, since it takes a function as parameter.
If b has an arrow, like a -> (c -> d), then this is a higher order function as well, since it returns a function.
Yes, as Haskell functions are curried always, I can come up with minimal examples of higher order functions and examples:
1) Functions that takes a function at least as parameter, such as:
apply :: (a -> b) -> a -> b
apply f x = f x
2) at least 3 arguments:
sum3 :: Int -> Int -> Int
sum3 a b c = a + b + c
so that can be read as:
sum3 :: Int -> (Int -> Int)

How to work around F#'s type system

In Haskell, you can use unsafeCoerce to override the type system. How to do the same in F#?
For example, to implement the Y-combinator.
I'd like to offer a different solution, based on embedding the untyped lambda calculus in a typed functional language. The idea is to create a data type that allows us to change between types α and α → α, which subsequently allows to escape the restrictions of a type system. I'm not very familiar with F# so I'll give my answer in Haskell, but I believe it could be adapted easily (perhaps the only complication could be F#'s strictness).
-- | Roughly represents morphism between #a# and #a -> a#.
-- Therefore we can embed a arbitrary closed λ-term into #Any a#. Any time we
-- need to create a λ-abstraction, we just nest into one #Any# constructor.
--
-- The type parameter allows us to embed ordinary values into the type and
-- retrieve results of computations.
data Any a = Any (Any a -> a)
Note that the type parameter isn't significant for combining terms. It just allows us to embed values into our representation and extract them later. All terms of a particular type Any a can be combined freely without restrictions.
-- | Embed a value into a λ-term. If viewed as a function, it ignores its
-- input and produces the value.
embed :: a -> Any a
embed = Any . const
-- | Extract a value from a λ-term, assuming it's a valid value (otherwise it'd
-- loop forever).
extract :: Any a -> a
extract x#(Any x') = x' x
With this data type we can use it to represent arbitrary untyped lambda terms. If we want to interpret a value of Any a as a function, we just unwrap its constructor.
First let's define function application:
-- | Applies a term to another term.
($$) :: Any a -> Any a -> Any a
(Any x) $$ y = embed $ x y
And λ abstraction:
-- | Represents a lambda abstraction
l :: (Any a -> Any a) -> Any a
l x = Any $ extract . x
Now we have everything we need for creating complex λ terms. Our definitions mimic the classical λ-term syntax, all we do is using l to construct λ abstractions.
Let's define the Y combinator:
-- λf.(λx.f(xx))(λx.f(xx))
y :: Any a
y = l (\f -> let t = l (\x -> f $$ (x $$ x))
in t $$ t)
And we can use it to implement Haskell's classical fix. First we'll need to be able to embed a function of a -> a into Any a:
embed2 :: (a -> a) -> Any a
embed2 f = Any (f . extract)
Now it's straightforward to define
fix :: (a -> a) -> a
fix f = extract (y $$ embed2 f)
and subsequently a recursively defined function:
fact :: Int -> Int
fact = fix f
where
f _ 0 = 1
f r n = n * r (n - 1)
Note that in the above text there is no recursive function. The only recursion is in the Any data type, which allows us to define y (which is also defined non-recursively).
In Haskell, unsafeCoerce has the type a -> b and is generally used to assert to the compiler that the thing being coerced actually has the destination type and it's just that the type-checker doesn't know it.
Another, less common use, is to reinterpret a pattern of bits as another type. For example an unboxed Double# could be reinterpreted as an unboxed Int64#. You have to be sure about the underlying representations for this to be safe.
In F#, the first application can be achieved with box |> unbox as John Palmer said in a comment on the question. If possible use explicit type arguments to make sure that you don't accidentally have the wrong coercion inferred, e.g. box<'a> |> unbox<'b> where 'a and 'b are type variables or concrete types that are already in scope in your code.
For the second application, look at the BitConverter class for specific conversions of bit-patterns. In theory you could also do something like interfacing with unmanaged code to achieve this, but that seems very heavyweight.
These techniques won't work for implementing the Y combinator because the cast is only valid if the runtime objects actually do have the target type, but with the Y combinator you actually need to call the same function again but with a different type. For this you need the kinds of encoding tricks mentioned in the question John Palmer linked to.

SML conversions to Haskell

A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c

Resources