I've run into a problem I don't really understand. I thought that I would be able to write code like this in Haskell:
foo :: Maybe Int -> Int
foo Nothing = 0
foo Just x = x
But when I try to compile it, I get the error:
Equations for ‘foo’ have different numbers of arguments
I can fix it by changing my code to the following:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x
Which makes me think that GHC is interpreting Just as an argument to foo. But Haskell forbids using uppercase letters to start variable names, so I wouldn't think there should be any ambiguity here. What's going on?
You're correct, there's not ambiguity about whether or not Just is a constructor – but constructors can have no arguments! Haskell's pattern matching doesn't look up the names involved, it's strictly syntactic, and foo Just x = x is a perfectly well-formed function definition clause. It's ill-typed:
Prelude> let foo Just x = x
<interactive>:2:9:
Constructor ‘Just’ should have 1 argument, but has been given none
In the pattern: Just
In an equation for ‘foo’: foo Just x = x
but with different data types around, it'd be fine:
Prelude> data Justice = Just
Prelude> let foo Just x = x
Prelude> :t foo
foo :: Justice -> t -> t
Prelude> foo Just ()
()
Just could be a nullary constructor (as in the second example), and since function application is left-associative, the compiler parses Just and x as separate arguments and you get the "different numbers of arguments" error. (And as you can see above, if there weren't the Nothing case, you'd actually get the type error for code of that form.)
The idea is that pattern syntax should mirror application syntax. If I was calling foo I couldn't write foo Just x, because that means something else (and if foo had type (Int -> Maybe Int) -> Int -> Int then it would even work). Having patterns have different rules for where parentheses are needed than expressions would be very weird.
Writing compound patterns without parentheses and trusting the compiler to automatically group things also falls apart in more complex situations. What should this mean?
foo Just x : xs = ...
Related
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.
Suppose I write in GHCi:
GHCi> let x = 1 + 2 :: Integer
GHCi> seq x ()
GHCi> :sprint x
GHCi prints x = 3 as naturally expected.
However,
GHCi> let x = 1 + 2
GHCi> seq x ()
GHCi> :sprint x
yields x = _
The sole difference between the two expressions are their types (Integer vs Num a => a). My question is what exactly happens, and why is seemingly x not evaluated in the latter example.
The main issue is that
let x = 1 + 2
defines a polymorphic value of type forall a. Num a => a, and that is something which evaluates similarly to a function.
Each use of x can be made at a different type, e.g. x :: Int, x :: Integer, x :: Double and so on. These results are not "cached" in any way, but recomputed every time, as if x were a function which is called multiple times, so to speak.
Indeed, a common implementation of type classes implements such a polymorphic x as a function
x :: NumDict a -> a
where the NumDict a argument above is added by the compiler automatically, and carries information about a being a Num type, including how to perform addition, how to interpret integer literals inside a, and so on. This is called the "dictionary-passing" implementation.
So, using a polymorphic x multiple times indeed corresponds to invoking a function multiple times, causing recomputation. To avoid this, the (dreaded) Monomorphism Restriction was introduced in Haskell, forcing x to be monomorphic instead. The MR is not a perfect solution, and can create some surprising type errors in certain cases.
To alleviate this issue, the MR is disabled by default in GHCi, since in GHCi we don't care that much about performance -- usability is more important there. This however causes the recomputation to reappear, as you discovered.
When I try to pattern-match a GADT in an proc syntax (with Netwire and Vinyl):
sceneRoot = proc inputs -> do
let (Identity camera :& Identity children) = inputs
returnA -< (<*>) (map (rGet draw) children) . pure
I get the (rather odd) compiler error, from ghc-7.6.3
My brain just exploded
I can't handle pattern bindings for existential or GADT data constructors.
Instead, use a case-expression, or do-notation, to unpack the constructor.
In the pattern: Identity cam :& Identity childs
I get a similar error when I put the pattern in the proc (...) pattern. Why is this? Is it unsound, or just unimplemented?
Consider the GADT
data S a where
S :: Show a => S a
and the execution of the code
foo :: S a -> a -> String
foo s x = case s of
S -> show x
In a dictionary-based Haskell implementation, one would expect that the value s is carrying a class dictionary, and that the case extracts the show function from said dictionary so that show x can be performed.
If we execute
foo undefined (\x::Int -> 4::Int)
we get an exception. Operationally, this is expected, because we can not access the dictionary.
More in general, case (undefined :: T) of K -> ... is going to produce an error because it forces the evaluation of undefined (provided that T is not a newtype).
Consider now the code (let's pretend that this compiles)
bar :: S a -> a -> String
bar s x = let S = s in show x
and the execution of
bar undefined (\x::Int -> 4::Int)
What should this do? One might argue that it should generate the same exception as with foo. If this were the case, referential transparency would imply that
let S = undefined :: S (Int->Int) in show (\x::Int -> 4::Int)
fails as well with the same exception. This would mean that the let is evaluating the undefined expression, very unlike e.g.
let [] = undefined :: [Int] in 5
which evaluates to 5.
Indeed, the patterns in a let are lazy: they do not force the evaluation of the expression, unlike case. This is why e.g.
let (x,y) = undefined :: (Int,Char) in 5
successfully evaluates to 5.
One might want to make let S = e in e' evaluate e if a show is needed in e', but it feels rather weird. Also, when evaluating let S = e1 ; S = e2 in show ... it would be unclear whether to evaluate e1, e2, or both.
GHC at the moment chooses to forbid all these cases with a simple rule: no lazy patterns when eliminating a GADT.
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).
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