Understanding the type error: "expected signature Int*Int->Int but got Int*Int->Int" - haskell

The comments on Steve Yegge's post about server-side Javascript started discussing the merits of type systems in languages and this comment describes:
... examples from H-M style systems where you can get things like:
expected signature Int*Int->Int but got Int*Int->Int
Can you give an example of a function definition (or two?) and a function call that would produce that error? That looks like it might be quite hard to debug in a large-ish program.
Also, might I have seen a similar error in Miranda? (I have not used it in 15 years and so my memory of it is vague)

I'd take Yegge's (and Ola Bini's) opinions on static typing with a grain of salt. If you appreciate what static typing gives you, you'll learn how the type system of the programming language you choose works.
IIRC, ML uses the '*' syntax for tuples. <type> * <type> is a tuple type with two elements. So, (1, 2) would have int * int type.
Both Haskell and ML use -> for functions. In ML, int * int -> int would be the type of a function that takes a tuple of int and int and maps it to an int.
One of the reasons you might see an error that looks vaguely like the one Ola quoted when coming to ML from a different language, is if you try and pass arguments using parentheses and commas, like one would in C or Pascal, to a function that takes two parameters.
The trouble is, functional languages generally model functions of more than one parameter as functions returning functions; all functions only take a single argument. If the function should take two arguments, it instead takes an argument and returns a function of a single argument, which returns the final result, and so on. To make all this legible, function application is done simply by conjunction (i.e. placing the expressions beside one another).
So, a simple function in ML (note: I'm using F# as my ML) might look a bit like:
let f x y = x + y;;
It has type:
val f : int -> int -> int
(A function taking an integer and returning a function which itself takes an integer and returns an integer.)
However, if you naively call it with a tuple:
f(1, 2)
... you'll get an error, because you passed an int*int to something expecting an int.
I expect that this is the "problem" Ola was trying to cast aspersions at. I don't think the problem is as bad as he thinks, though; certainly, it's far worse in C++ templates.

It's possible that this was in reference to a badly-written compiler which failed to insert parentheses to disambiguate error messages. Specifically, the function expected a tuple of int and returned an int, but you passed a tuple of int and a function from int to int. More concretely (in ML):
fun f g = g (1, 2);
f (42, fn x => x * 2)
This will produce a type error similar to the following:
Expected type int * int -> int, got type int * (int -> int)
If the parentheses are omitted, this error can be annoyingly ambiguous.
It's worth noting that this problem is far from being specific to Hindley-Milner. In fact, I can't think of any weird type errors which are specific to H-M. At least, none like the example given. I suspect that Ola was just blowing smoke.

Since many functional language allow you to rebind type names in the same way you can rebind variables, it's actually quite easy to end up with an error like this, especially if you use somewhat generic names for your types (e.g., t) in different modules. Here's a simple example in OCaml:
# let f x = x + 1;;
val f : int -> int = <fun>
# type int = Foo of string;;
type int = Foo of string
# f (Foo "hello");;
This expression has type int but is here used with type int
What I've done here is rebind the type identifier int to a new type that is incompatible with the built-in int type. With a little bit more effort, we can get more-or-less the same error as above:
# let f g x y = g(x,y) + x + y;;
val f : (int * int -> int) -> int -> int -> int = <fun>
# type int = Foo of int;;
type int = Foo of int
# let h (Foo a, Foo b) = (Foo a);;
val h : int * int -> int = <fun>
# f h;;
This expression has type int * int -> int but is here used with type
int * int -> int

Related

How do you define a function type in Haskell?

I'm trying to store a function type in a definition so I can reuse it, but Haskell doesn't let me do it. A function type is not a data type , nor a class, as far as I understand them. So what am I doing wrong please?
functionType = Int -> Int -> Int -> Int -> Int -> Int -> Int
myfunction :: functionType -- <-- how do I declare this thing in a definition?
myfunction a b c d e f = a*b*c*d*e*f
Type aliases use the type keyword in their declaration; also, as usual for the declaration of new type forms, the newly declared alias must start with an upper case letter*. So:
type FunctionType = Int -> Int -- -> ...
functionValue :: FunctionType
functionValue a = a
* ...or punctuation. Why doesn't the usual "upper-case" punctuation restriction apply? No idea. I never thought about it before trying to write this answer, and now that I have, I find that a bit weird. Perhaps the upper-case restriction on the declaration of new types should be removed!

Haskell Illegal term-level use of the type constructor 'Int'

I'm very new to Haskell and am trying to multiply a number by itself as followed:
Test :: Int -> Int
Test = Int * Int
Doing this gave me the following error ' Illegal term-level use of the type constructor ‘Int’'
In the first argument of ‘(*)’, namely ‘Int’
In the expression: Int * Int
In an equation for 'Test': Test = Int * Int
I'm pretty confused from this message. Can anyone explain what went wrong with this implementation?
Int is a type, not a value or expression.
Also note that by convention, tokens starting with an uppercase denote a type, typeclass, or type constructor. For functions, you want to start with a lower case.
test :: Int -> Int
test n = n * n
If you're in need of a haskell resource, I strongly suggest reading Learn You a Haskell. It covers all these basics and more.

Why can you define function without parameter in 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).

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

F# Type declaration possible ala Haskell?

I've looked a number of sources: it seems not possible to declare a type definition in F# ala Haskell:
' haskell type def:
myFunc :: int -> int
I'd like to use this type-def style in F#--FSI is happy to echo back to me:
fsi> let myType x = x +1;;
val myType : int -> int
I'd like to be explicit about the type def signature in F# as in Haskell. Is there a way to do this? I'd like to write in F#:
//invalid F#
myFunc : int -> int
myFunc x = x*2
The usual way is to do let myFunc (x:int):int = x+1.
If you want to be closer to the haskell style, you can also do let myFunc : int -> int = fun x -> x+1.
If you want to keep readable type declarations separately from the implementation, you can use 'fsi' files (F# Signature File). The 'fsi' contains just the types and usually also comments - you can see some good examples in the source of F# libraries. You would create two files like this:
// Test.fsi
val myFunc : int -> int
// Test.fs
let myFunx x = x + 1
This works for compiled projects, but you cannot use this approach easily with F# Interactive.
You can do this in F# like so to specify the return value of myType.
let myType x : int = x + 1
You can specify the type of the parameter, too.
let myType (x : int) : int = x + 1
Hope this helps!
See also The Basic Syntax of F# - Types (which discusses this aspect a little under 'type annotations').
Another option is to use "type abbreviations" (http://msdn.microsoft.com/en-us/library/dd233246.aspx)
type myType = int -> int
let (myFunc : myType) = (fun x -> x*2)
yes you can, by using lambda functions
myFunc : int -> int =
fun x -> x*2
this also avoids the problem in haskell of writing the function name twice.

Resources