The following code
------------------------------------------------------
module Remove() where
f :: a -> [a] -> [a] -- Remove an element
f x [] = []
f x (x:whatever) = whatever
f x (y:whatever) = x:whatever
------------------------------------------------------
Gives an error:
Reading file "remove.hs":
Dependency analysis
ERROR "remove.hs" (line 5): Repeated variable "x" in pattern
Why is it that a variable can't be repeated and how am I supposed to do
this (construct a generic element removal function)
Alec
P.S. On a different note, what's an arity?
> Hi
>
> The following code
> ------------------------------------------------------
> module Remove() where
>
> f :: a -> [a] -> [a] -- Remove an element
> f x [] = []
> f x (x:whatever) = whatever
> f x (y:whatever) = x:whatever
> ------------------------------------------------------
I meant
f x (y:whatever) = x: f whatever
in the last line of course. (Same error)
I forget the technical reasons why this isn't allowed, but you can do
it with a guard. Where you want to write
f x x = blurp
f x y = blop
write
f x y | x == y = blurp
| otherwise = blop
> > Alec
> > P.S. On a different note, what's an arity?
the number of parameters something takes.
--
Jón Fairbairn Jon.Fa...@cl.cam.ac.uk
Jón> I forget the technical reasons why this isn't allowed, but
Jón> you can do it with a guard. Where you want to write
Jón> f x x = blurp f x y = blop write
Jón> f x y | x == y = blurp | otherwise = blop
This has the type f :: (Eq a) -> a -> a -> something.
I think that Miranda allowed `non-linear' (repeated) parameters when
defining a function. It seems there are two choices:
1. Allow f x x = ... as sugar for f x y | x == y = ...
2. Insist on non-repetitious parameter lists, and that
equality guards are put in explicitly.
The Right Choice is 2, ISTM. It catches more mistakes.
Peter Hancock
> Alec <alecANTIS...@yahoo.com> writes:
> Where you want to write
>
> f x x = blurp
> f x y = blop
> write
>
> f x y | x == y = blurp
> | otherwise = blop
This modified code:
------------------------------------------------------
module Remove() where
f :: a -> [a] -> [a] -- Remove an element
f x [] = []
f x (y:whatever) | x == y = f x whatever
| otherwise = y: f x whatever
------------------------------------------------------
still gives an error (but a different one):
Reading file "remove.hs":
Type checking
ERROR "remove.hs" (line 5): Cannot justify constraints in explicitly typed
binding
*** Expression : f
*** Type : a -> [a] -> [a]
*** Given context : ()
*** Constraints : Eq a
Thanks
Alec
>>>>>> "Jón" == Jón Fairbairn <j...@cl.cam.ac.uk> writes:
>
> Jón> I forget the technical reasons why this isn't allowed, but
> Jón> you can do it with a guard. Where you want to write
>
> Jón> f x x = blurp f x y = blop write
>
> Jón> f x y | x == y = blurp | otherwise = blop
>
> This has the type f :: (Eq a) -> a -> a -> something.
>
> I think that Miranda allowed `non-linear' (repeated) parameters when
> defining a function. It seems there are two choices:
>
> 1. Allow f x x = ... as sugar for f x y | x == y = ...
Not only that, why not allow
f g(x) h(x) = ... as "sugar" for f g(x) h(y) | x == y = ...?
Alec
You've told it that f is a polymorphic function (working for _all_ a),
but then used equality and prevented it from working on types that
don't have equality.
Either omit the type declaration and let the compiler discover the
type, or write something more honest like:
f :: Eq a => a -> [a] -> [a]
--
Jón Fairbairn Jon.Fa...@cl.cam.ac.uk
> Not only that, why not allow
> f g(x) h(x) = ... as "sugar" for f g(x) h(y) | x == y = ...?
That syntax is no good since f g(x) h(x) = ... is syntactically
the same as f g x h x
f (g == x) (h == x) might work, but you aren't gaining much. Guards
are a more general mechanism since you can write f x y | x < y = . . .
--
Jón Fairbairn Jon.Fa...@cl.cam.ac.uk
> Either omit the type declaration and let the compiler discover the
> type,
This finally works. Thanks!
> or write something more honest like:
>
> f :: Eq a => a -> [a] -> [a]
What does "Eq a" mean?
Alec
alecANTISPAM314159> Not only that, why not allow f g(x) h(x) =
alecANTISPAM314159> ... as "sugar" for f g(x) h(y) | x == y = ...?
Do you mean allowing patterns (built out of constructors) in which the
pattern variables needn't be distinct?
On the face of it that seems a sensible idea, if you are going to allow
the variables in (uninformative) "x" patterns to be repeated, and explain
it with equality guards.
I still think it is a very sound idea that when you are defining a
function, by pattern matching or not, the parameters should be
distinct.
[If anyone is interested, this is a really interesting question for
dependent type systems: whether they admit a generic identity type, having
a definition something like
> data Id (A : Type) (a : A) (a : A) = Refl (a : A)
with repeated parameters.]
--
Peter Hancock
a is part of the Eq class.
--
Gaurav Sharma
To elaborate a little further, in f :: Eq a => a -> [a] -> [a], "Eq a
=>" is a context that requires that the variable a in the rest of the
type belong to the class Eq.
The standard prelude defines Eq like this:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
in other words, that context says that f will work for any type a if a
has been made an instance of Eq, which in turn means that there is an
(==) operator for a. That's what you needed, after all.
--
Jón Fairbairn Jon.Fa...@cl.cam.ac.uk
How did the compiler in Alec's example know that "a" had to belong to
class "Eq"? I mean, any class that declares "==" would have matched,
right?
Olaf
> How did the compiler in Alec's example know that "a" had to belong to
> class "Eq"? I mean, any class that declares "==" would have matched,
> right?
I think you are mixing up the OO notion of class with the polymorphic
type notion of class. You aren't allowed to define type classes that
use the same function names as other type classes. So in Haskell, the
only class that has (==) is Eq.
For type classes, the names and types of the operators are what
defines them.
--
Jón Fairbairn Jon.Fa...@cl.cam.ac.uk