Equations for `someFunction' have different numbers of arguments - haskell

I'm using in order to practice/learn Haskell. I'm having trouble understanding why a given situation works on my example local code, and doesn't work on CodeWars.
On codewars:
module Codewars.Kata.Negative where
makeNegative :: (Num a) => a -> a
makeNegative x = x + x
makeNegative = error "todo: makeNegative"
This gives me:
Codewars/Kata/Negative.hs:4:1:
Equations for `makeNegative' have different numbers of arguments
Codewars/Kata/Negative.hs:4:1-22
Codewars/Kata/Negative.hs:5:1-41
But when I test it locally:
import Data.List
import System.IO
example :: (Num a) => a -> a
example x = x + x
main = do
print (example(3))
It returns 6 properly. I can't even try to solve the problem because the compiler complains about the arguments. I kinda got it that Num is a "typeclass", but I don't get how that works differently on codewars. I guess its because of that "where" clause there.

The problem lies in your definition of makeNegative. Notice there's three lines of the definition:
makeNegative :: (Num a) => a -> a
makeNegative x = x + x
makeNegative = error "todo: makeNegative"
The first is the type signature, followed by two definitions. Oftentimes multiple definitions are provided when pattern matching on arguments and handling different cases; however in this case the pattern match will never fail; so the error line will never run.
Regardless of the fact that it will never be run; Haskell still requires that all implementations of a function have the same number of bound arguments, makeNegative x = binds one argument (namely x); but the second definition makeNegative = doesn't bind any arguments. In this case it looks like it's a placeholder definition so you can just delete the line with error and it should work.
Your example test only has a single definition, so it doesn't run into this issue.

Related

Haskell beginners array creation

I have been struggling with a rather simple thing in Haskell and since I cannot understand what is and why is blocking me I though it would be a good idea to ask here. I would like to create a function that deletes numbers in a given array that are exactly the same as the previous one was. So, for example, from array: [12,12,3,4,5,5,5,7,9] I would like to get an output of: [12,3,4,5,7,9]. Based on that I wrote:
removeDuplicates[x] = x
removeDuplicates(x:y:ys) | x == y = removeDuplicates(x:ys)
| otherwise = x ++ removeDuplicates([]:y:ys)
... but after succesfully loading the code I get an error of:
* Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall a. (Eq a, Num [a]) => [a]
I understand there is something wrong with my otherwise statement and type of returned value, but since I am a total beginner in Haskell I don't know how to solve this rather funny than serious problem.

Haskell - passing a function as a argument compilation error

I have a very simple function called 'fold' that takes a function f and executes it. Given a function 'add' and two numbers it calls add with those two numbers and displays the results. However I cannot compile it due to a compilation error below. What is the error specifically stating and what can I do to solve it?
module Main where
add x y = x + y
--fold :: ((a,b)->c) -> a->b->c
fold f n x = f n x
main :: IO ()
main = do
fold add 2 3
The problem is that you've declared main (correctly) as having type IO (), but fold doesn't return that. The error message is a little more complicated because in theory, add (and thus fold) could return a value of type IO (), since add can return any type with a Num instance. IO (), however, is not an instance of Num. The solution is to return an IO action created from the return value of fold. One way to do that is to use the print function (which takes any value with a Show instance and converts it to a String before outputing it).
main = print $ fold add 2 3

Different numbers of arguments when pattern matching Maybe

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 = ...

Haskell type dessignation

I have to dessignate types of 2 functions(without using compiler :t) i just dont know how soudl i read these functions to make correct steps.
f x = map -1 x
f x = map (-1) x
Well i'm a bit confuse how it will be parsed
Function application, or "the empty space operator" has higher precedence than any operator symbol, so the first line parses as f x = map - (1 x), which will most likely1 be a type error.
The other example is parenthesized the way it looks, but note that (-1) desugars as negate 1. This is an exception from the normal rule, where operator sections like (+1) desugar as (\x -> x + 1), so this will also likely1 be a type error since map expects a function, not a number, as its first argument.
1 I say likely because it is technically possible to provide Num instances for functions which may allow this to type check.
For questions like this, the definitive answer is to check the Haskell Report. The relevant syntax hasn't changed from Haskell 98.
In particular, check the section on "Expressions". That should explain how expressions are parsed, operator precedence, and the like.
These functions do not have types, because they do not type check (you will get ridiculous type class constraints). To figure out why, you need to know that (-1) has type Num n => n, and you need to read up on how a - is interpreted with or without parens before it.
The following function is the "correct" version of your function:
f x = map (subtract 1) x
You should be able to figure out the type of this function, if I say that:
subtract 1 :: Num n => n -> n
map :: (a -> b) -> [a] -> [b]
well i did it by my self :P
(map) - (1 x)
(-)::Num a => a->a->->a
1::Num b=> b
x::e
map::(c->d)->[c]->[d]
map::a
a\(c->d)->[c]->[d]
(1 x)::a
1::e->a
f::(Num ((c->d)->[c]->[d]),Num (e->(c->d)->[c]->[d])) => e->(c->d)->[c]->[d]

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