I am currently learning how to write type classes. I can't seem to write the Ord type class with compile errors of ambiguous occurrence.
module Practice where
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>=), (>) :: a -> a -> Bool
max, min :: a -> a -> a
-- Minimal complete definition:
-- (<=) or compare
-- Using compare can be more efficient for complex types.
compare x y
| x == y = EQ
| x <= y = LT
| otherwise = GT
x <= y = compare x y /= GT
x < y = compare x y == LT
x >= y = compare x y /= LT
x > y = compare x y == GT
-- note that (min x y, max x y) = (x,y) or (y,x)
max x y
| x <= y = y
| otherwise = x
min x y
| x <= y = x
| otherwise = y
Errors are
Practice.hs:26:14:
Ambiguous occurrence `<='
It could refer to either `Practice.<=', defined at Practice.hs:5:10
or `Prelude.<=',
imported from `Prelude' at Practice.hs:1:8-15
...
and so on. I think it is clashing with the Prelude defined version.
The problem is that the names of your functions are clashing with the standard ones from the Prelude.
To solve this, you can add an explicit import declaration which hides the conflicting names:
module Practice where
import Prelude hiding (Ord, compare, (<), (<=), (>=), (>), max, min)
...
hammar is right, it's because of clashing with standard Prelude names. But there are another solutions in addition to hiding names from Prelude.
You can import Prelude qualified:
module Practice where
import qualified Prelude as P
...
Next, you can gain access to both you and standard version of function: max will execute your version, and P.max will execute standard Prelude's.
There is also way to completely hide all standard Prelude functions: GHC's extension NoImplicitPrelude (http://www.haskell.org/haskellwiki/No_import_of_Prelude). It can be activated writing
{-# LANGUAGE NoImplicitPrelude #-}
in the very beginning of your file
Related
How can I define a function with the following signature,
f :: [Int???] -> [Int]
f xs = _ -- what I do with xs doesn't matter for the question
where a is a List of Int's
such that the first argument's inputs, i.e. list elements, must be >= 0, but <= 5 at compile-time?
In other words,
f [6] would fail to compile.
How about:
f :: [Int] -> [Int]
f = filter (\x -> x >= 0 && x <= 5)
Or do you want to enforce the bounds on the type (dependent types)?
If you want to restrict the range of the Int that is allowed you are probably better of using a smart constructor. Have a look here. The idea is that you create your own datatype and your own custom constructor:
newtype Range0_5 = Range0_5 { unRange :: Int }
makeRange0_5 :: Int -> Maybe Range0_5
makeRange0_5 x
| x >= 0 && x <= 5 = Just $ Range0_5 x
| otherwise = Nothing
If you make a smart constructor, it is important to not expose it to the user of the module. This can be done by simply not exporting the Range0_5 constructor.
However this is not a compile time check. Other languages than Haskell might be more appropriate if you really need such a feature.
Since the range is fairly small, you could also make a sum type to represent it:
data Range0_5 = Int0 | Int1 | Int2 | Int3 | Int4 | Int5
If the signature is
f :: [Int] -> [Int]
(which was the original form of the question), then it is impossible to enforce your constraint at compile time. This follows from the standard diagonalization argument of the Halting problem.
Suppose the compiler could detect that
f[g x]
should not compile. By incorporating the source code of the compiler into g, it could choose the opposite of the compiler's decision.
Following your comment on Liquid Haskell (which seems like a very interesting project), note the following:
{-# type Even = {v:Int | v mod 2 = 0} #-}
{-# foo :: n:Even -> {v:Bool | (v <=> (n mod 2 == 0))} #-}
foo :: Int -> Bool
foo n = if n^2 - 1 == (n + 1) * (n - 1) then True else foo (n - 1)
LiquidHaskell claims this function is unsafe, because, potentially foo n calls foo (n - 1). Note, however, that this will never happen: it will only be called if the relationship n2 - 1 ≠ (n + 1) (n - 1), which can never happen.
Again, this is not a criticism of the quality of LiquidHaskell, but rather just pointing out that it, too, cannot solve Halting Problem like issues.
In Haskell we have the function (==) :: Eq a => a->a->Bool which is fine for the large number of datatypes for which an instance of Eq can be defined. However there are some types for which there is no reasonable way to define an instance of Eq. one example is the simple function type (a->b)
I am looking for a function that will tell me if two values are actually the same -- not equal but identical.
For example f(id,id) ==> True f((+),(-)) = False
Clarification:
I don't want to know if two function do the same thing. It is not possible in the general case to do so. I want to know if I've gotten back the same thing I started with. Let me give a stripped down example:
data Foo = Foo (Foo->Foo) --contains a function so no Eq instance
x :: Foo
x = Foo id -- or for that matter Foo undefined
y :: Foo
y = Foo (const x)
a :: Foo
a = let (Foo fy) = y
in fy x
It is clear that by inspection once evaluated, a will be x. But let's assume I don't know the function in y but I want to test if the Foo I put in is the same one I got back - that is does fy x give me x. How do I do this?
One way that wasn't mentioned in Pointer equality in Haskell? is reallyUnsafePtrEquality#. As the name suggests it can be unpredictable and probably should't be used but it can be interesting to see how ghc works. Here's how you can use it in ghci:
> :set -package ghc-prim
> import GHC.Prim
> import GHC.Types
> isTrue# (reallyUnsafePtrEquality# id id)
True
> let a x = x + 2 :: Int
> isTrue# (reallyUnsafePtrEquality# a a)
True
> let b x = x + 2 :: Int
> isTrue# (reallyUnsafePtrEquality# a b)
False
If the function isn't monomorphic it doesn't work:
> let c x = x + 2
> isTrue# (reallyUnsafePtrEquality# c c)
False
Some more examples:
> let d = c in isTrue# (reallyUnsafePtrEquality# d d)
False
> :set -XMonomorphismRestriction
> let d = c in isTrue# (reallyUnsafePtrEquality# d d)
True
You can compare polymorphic types if you wrap them in a newtype:
> :set -XRankNTypes
> newtype X = X (forall a. Num a => a -> a)
> let d = X c
> isTrue# (reallyUnsafePtrEquality# d d)
True
Applying anything makes them not equal
> isTrue# (reallyUnsafePtrEquality# (id ()) (id ()))
False
But when compiling with optimisations this is True.
Hopefully this is enough to convince you that what you want is a bad idea. One of the solutions in Pointer equality in Haskell? would be a better.
Given this data type
data Val = X Int | Y Bool | Z Double deriving (Eq, Show)
and a list such as
let vals = [X 1, Z 2.7, Y True, X 2, Z 3.14, Y True]
how to group elements in vals into this list,
[[X 1,X 2],[Y True,Y True],[Z 2.7, Z 3.14]]
To add to #RamonSnir's answer, the function for grouping a data type by constructors can be also constructed automatically using the "Scrap your boilerplate" framework:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Function (on)
import Data.List (groupBy, sort)
data Val = X Int | Y Bool | Z Double
deriving (Eq, Ord, Show, Typeable, Data)
vals :: [Val]
vals = [X 1, Z 2.7, Y True, X 2, Z 3.14, Y True]
main :: IO ()
main = print $ groupBy (on (==) toConstr) $ sort vals
The two important parts are:
derive Typeable and Data, and
use toConstr to get the representation of the constructor used in a particular value.
I've the following:
data Val = X Int | Y Bool | Z Double deriving (Eq, Ord, Show)
vals :: [Val]
vals = [X 1, Z 2.7, Y True, X 2, Z 3.14, Y True]
valCtorEq :: Val -> Val -> Bool
valCtorEq (X _) (X _) = True
valCtorEq (Y _) (Y _) = True
valCtorEq (Z _) (Z _) = True
valCtorEq _ _ = False
And then:
*Main Data.List> groupBy valCtorEq $ sort vals
[[X 1,X 2],[Y True,Y True],[Z 2.7,Z 3.14]]
(This is probably extreme overkill, but it was a fun question to tinker around with!)
The provided answers suffer from 3 slight problems:
What if the type under consideration isn't in Ord (because for example, there's a function in there somewhere)?
Also, should this operation be O(n log n) in the length of the list?
Finally, the example provided isn't sufficient to determine whether the grouping should be stable, that is: should the result of grouping [X 2, X 1] be [X 1, X 2] (that's what you get if you use the sort-based solutions) or should the elements be kept in their original order?
So here is the most general solution I could come up with. It's stable, it doesn't need Ord (in fact you don't even need to touch the original datatype) and it runs in about O(n * min(n,W)) time where W is the word size of your machine (on mine, it's 64). That is, it's linear once the list gets longer than 64-ish elements (I say 'about', because the grouped elements still need to be reconstituted from the difference lists).
{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
import Data.Data
import qualified Data.IntMap as IM
groupByConstructor :: Data a => [a] -> [[a]]
groupByConstructor = map ($ []) . IM.elems . IM.fromListWith (flip (.))
. map (\a -> (constrIndexOf a, (a:))) where constrIndexOf = constrIndex . toConstr
-- definition of Val as originally posed, without Ord:
data Val = X Int | Y Bool | Z Double deriving (Eq, Show)
deriving instance Typeable Val
deriving instance Data Val
-- new example:
vals = [X 2, Z 2.7, Y True, X 1, Z 3.14, Y False, Z 0.2]
and now groupByConstructor vals gives [[X 2, X 1],[Y True, Y False],[Z 2.7, Z 3.14, Z 0.2]] as I think it should.
It doesn't work for sorting lists of Ints, Chars, Floats, or non-representable types such as Ptr and Array. It could probably be made a bit more efficient by using an algorithm which uses the number of possible constructors to push the linear constant down further but IntMap will have to do for now :-)
I want to overload any operator . i want to do such a simple function that for instance think about overloading of == operator .Overload == such that
x==y
returns x .
Or x==y return x+y. It doesn't matter what . Can you show me any simple operator overloading example? I cannot find any example on the web unfortunately.
For example;when i call Tree a == Tree a
return 5 (it always return 5. I select it ,it is not related to any thing)
or when i call 3==4
return : 7
I tried the below codes(i find it from haskell.org) but it cannot compile.
class Eq a where
(==) ::a -> a -> Int
instance Eq Integer where
x == y = 5
instance Eq Float where
x == y = 5
Neither the below code works:
data Tree a = Node a | Empty
class Tree a where
(==) :: Tree a -> Tree a -> Int
instance Tree Integer where
x == y = 1
I take the error :
Ambiguous occurrence `Eq'
It could refer to either `Main.Eq', defined at Operations.hs:4:7
or `Prelude.Eq',
imported from `Prelude' at Operations.hs:1:1
(and originally defined in `GHC.Classes')
You can't hide instances from an imported module. See for example: Explicitly import instances
It looks like the "overloading" you're trying to do is to allow (==) for other types, like trees. This is easy! Just simply create a new instance:
data Tree a = Leaf a | Branch [Tree a]
instance (Eq a) => Eq (Tree a) where
(Leaf a) == (Leaf b) = a == b
(Branch a) == (Branch b) = a == b
_ == _ = False
(You could also just derive the Eq instance)
Try hiding the == from the Prelude first. You only need a type class if you want it to work differently for different types.
import Prelude hiding ((==))
x == y = x
Here's a +++ operator that acts like the (++) operator used to append lists:
(+++) :: [a]->[a]->[a]
x +++ [] = x
[] +++ x = x
x +++ y = (init x) +++ ((last x) : y)
import Data.Function (on)
import Data.List (sort)
data Monomial = Monomial
{ m_coeff :: Coefficient
, m_powers :: [(Variable, Power)]
}
deriving ()
instance Ord Monomial where
(>=) = on (>=) m_powers
instance Eq Monomial where
(==) = on (==) m_powers
That's an excerpt from my code, cut down to principal size. Let's try comparing:
*Main> (Monomial 1 [("x",2)]) > (Monomial (-1) [])
/* Computation hangs here */
*Main> (Monomial 1 [("x",2)]) < (Monomial (-1) [])
/* Computation hangs here */
On a side note, it's interesting that if I replace s/(>=)/(>)/g in instance declaration, it will not hang on the fist pair, but still will on the second:
*Main> (Monomial 1 [("x",2)]) > (Monomial (-1) [])
True
*Main> (Monomial 1 [("x",2)]) < (Monomial (-1) [])
/* Computation hangs here */
Although the standard states minimal declaration of Eq instance to be either$compare$ or $(>=)$.
What might be the problem here? (>=) on lists seems to work just fine.
Short answer:
You need to provide either (<=) or compare to have a complete definition for Ord, not (>=).
Longer explanation:
It is common for type classes in Haskell to have default implementations of some methods implemented in terms of other methods. You can then choose which ones you want to implement. For example, Eq looks like this:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
Here, you must either implement (==) or (/=), otherwise trying to use either of them will cause an infinite loop. Which methods you need to provide is usually listed as the minimal complete definition in the documentation.
The minimal complete definition for Ord instances, as listed in the documentation, is either (<=) or compare. Since you've only provided (>=), you have not provided a complete definition, and therefore some of the methods will loop. You can fix it by e.g. changing your instance to provide compare instead.
instance Ord Monomial where
compare = compare `on` m_powers
Let's look at the default instance for Ord:
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
x <= y = case compare x y of { GT -> False; _ -> True }
x > y = case compare x y of { GT -> True; _ -> False }
x >= y = case compare x y of { LT -> False; _ -> True }
-- These two default methods use '<=' rather than 'compare'
-- because the latter is often more expensive
max x y = if x <= y then y else x
min x y = if x <= y then x else y
So, if you supply >= and == as above, only, then you are in trouble, since:
> is defined in terms of compare
But
compare is defined in terms of <=
<= is defined in terms of compare
So you have an infinite loop!
A minimum definition must defined <= or compare, not '>=`.