Haskell Enumerations starting from 1 - haskell

Consider the following method to create a start-at-1 enumeration in Haskell:
data Level = Lower | Middle | Upper
deriving (Show, Eq, Ord)
instance Enum Level where
toEnum 1 = Lower
toEnum 2 = Middle
toEnum 3 = Upper
fromEnum Lower = 1
fromEnum Middle = 2
fromEnum Upper = 3
instance Bounded Level where
minBound = Lower
maxBound = Upper
I'd rather not do the following:
data Level = DontUseThis | Lower | Middle | Upper
deriving (Show, Eq, Ord)
If not, is there a more straightforward way to do this?

First of all, you don't need to define the Bounded instance yourself. If you add Bounded to the list of derived typeclasses you should get identical behavior.
Secondly, the most straightforward way I can think of to accomplish this is to simply derive Enum and then define your own translation functions. So something like this:
data Level = Lower | Middle | Upper
deriving (Show, Eq, Ord, Bounded, Enum)
toEnum' x = toEnum (x - 1)
fromEnum' x = (fromEnum x) + 1

You can write it a little bit more concise (well, if you have more than 3 constructors) using:
import Data.List (elemIndex)
import Data.Maybet (fromJust)
values = [Lower, Middle, Upper]
instance Enum Level where
toEnum n = values !! (n-1)
fromEnum k = 1 + fromJust $ elemIndex k values

Related

Haskell instance function

I'm solving some exercises from a book and now I'm having some difficulties:
In this exercise I shall implement Card as an instance of the class Ord.
But I don't know how exactly I could implement it, so I would appreciate any help.
My code so far looks like this:
data Suit = Diamond | Club | Spade | Heart
data Rank = Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
data Card = Card Suit Rank
instance Ord Card where
....
Now I don't know how exactly to implement this and I would very much like to understand it.
Thanks in advance for the explanations.
We can ask GHCi for information about Ord.
:info Ord
This shows the class definition, followed by a list of instances.
type Ord :: * -> Constraint
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
max :: a -> a -> a
min :: a -> a -> a
{-# MINIMAL compare | (<=) #-}
-- Defined in ‘GHC.Classes’
Its superclass is Eq, and :info Eq tells us:
type Eq :: * -> Constraint
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
{-# MINIMAL (==) | (/=) #-}
-- Defined in ‘GHC.Classes’
So in order to implement Ord for Card, we need two things:
An instance Ord Card, with a definition of compare or (<=)
An instance Eq Card with a definition of (==) or (/=)
Since these instances are very mechanical to write, normally we ask the compiler to derive them automatically:
data Suit = Diamond | Heart | Spade | Club
deriving (Eq, Ord)
data Rank = Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
deriving (Eq, Ord)
data Card = Card Suit Rank
deriving (Eq, Ord)
If you pass the -ddump-deriv flag to GHC, or use :set -ddump-deriv in GHCi, it will print out the code that it generates for these instances.
However, the task is to understand how to implement these instances by hand, so let’s go through it step by step.
We’ll start with Eq. For Suit and Rank, we need to specify that each constructor is equal to itself (a.k.a. reflexivity) and all other constructors are unequal.
instance Eq Suit where
Diamond == Diamond = True
Heart == Heart = True
Spade == Spade = True
Club == Club = True
_ == _ = False
instance Eq Rank where
Seven == Seven = True
Eight == Eight = True
Nine == Nine = True
Ten == Ten = True
Jack == Jack = True
Queen == Queen = True
King == King = True
Ace == Ace = True
_ == _ = False
With that out of the way, we can define == for Card in a similar way, by pattern-matching on values of the form Card suit rank.
instance Eq Card where
-- Two cards are equal if…
Card suit1 rank1 == Card suit2 rank2
-- …their suits are equal,
-- and their ranks are equal.
= …
There are two conventional ways to define the body. One is spelling it out literally: suit1 == suit2 && rank1 == rank2. Another is to use tuples: (suit1, rank1) == (suit2, rank2).
Again, to define Ord, we can begin with the instances for the enumerations Suit and Rank. We have two choices of how to specify these: (<=) or compare. The direct option is to just list out the table of possible cases, abbreviating cases where we can:
instance Ord Suit where
Diamond <= _ = True
Heart <= Diamond = False
Heart <= _ = True
Spade <= Diamond = False
Spade <= Heart = False
Spade <= _ = True
Club <= Club = True
Club <= _ = False
instance Ord Rank where
…
For Card, we now just need to follow the same basic form as for Eq. Since we defined (<=) for Suit and Rank, note that we automatically get a default implementation of the other comparison functions like compare and (<) for those types.
instance Ord Card where
-- Two cards are in order if…
Card suit1 rank1 <= Card suit2 rank2
-- …one rank is less than the other,
-- or their ranks are equal and suits are in order.
= …
Again you can translate this comment verbatim using (<), (||), (==), (&&), (<=).
Try implementing these instances based on compare instead of (<=). Hint: use comparing and instance Monoid Ordering from Data.Ord.
Add deriving (Enum) to Rank and Suit—try using fromEnum to simplify their Eq and Ord definitions.
I can't imagine the exercise actually wanted you to manually write the necessary instances. Especially for Suit and Rank, they would be very tedious (and error prone) to write.
Instead, you probably want to use the deriving keyword to automatically derive the necessary instances. If you write:
data Suit = Diamond | Heart | Spade | Club
deriving (Eq, Ord)
this automatically derives Eq and Ord instances. (The Eq instance is required by the Ord instance.) The derived Eq instance is self-explanatory, and the derived Ord instance uses the order in which the constructors appear in the declaration, so Diamond is the smallest and Club is the biggest. If you want bridge order, use:
data Suit = Club | Diamond | Heart | Spade
deriving (Eq, Ord)
instead. Similarly,
data Rank = Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
deriving (Eq, Ord)
orders the rank from Seven (smallest) to Ace (largest). Then, if you write:
data Card = Card Rank Suit
deriving (Eq, Ord)
the derived instance sorts Cards according to the first field Rank, with ties broken by Suit. If you wrote:
data Card = Card Suit Rank
deriving (Eq, Ord)
it would instead order them by Suit, then Rank.
Some code to illustrate:
data Suit = Diamond | Heart | Spade | Club
deriving (Eq, Ord)
data Rank = Seven | Eight | Nine | Ten | Jack | Queen | King | Ace
deriving (Eq, Ord)
data Card = Card Rank Suit
deriving (Eq, Ord)
main = do
let heart8 = Card Eight Heart
spade8 = Card Eight Spade
diamond7 = Card Seven Diamond
print $ heart8 == heart8 -- True
print $ heart8 == spade8 -- False
print $ heart8 < spade8 -- True
print $ diamond7 < spade8 -- True

Haskell Bounded DataTypes, constructed from value-bounds

I have the following type in Haskell, to represent values between 0&23. There's more for handling the arithmetic; elided here for space.
newtype N24 = N_24 Word16
deriving (Enum, Eq, Integral, NFData, Ord, Real, Show)
toN24 ∷ (Integral α, Num α) ⇒ α → N24
toN24 n#(toInteger → n') | n' < toInteger (minBound #N24) = throw Underflow
| n' > toInteger (maxBound #N24) = throw Overflow
| otherwise = N_24 (fromIntegral n)
instance Bounded N24 where
minBound = N_24 0
maxBound = N_24 23
Now, I want to build a similar type for N60. And another for N12.
My question is, can I design a higher-order type(?), e.g., 'BoundedN' such that I could declare
n60 :: BoundedN 60
n12 :: BoundedN 12
that implemented the above, but without having to copy-and-paste the entire definition. I've tried to use Reflection, but honestly, I'm not understanding it and just bouncing on the keys trying to find stuff that works isn't getting me anywhere. I could do it with TemplateHaskell, but I consider that a last resort (at best, it will be relatively hard to read, I fear).
It is possible to design such a type; indeed, it has already been done! The finite-typelits library defines a type Finite n, which can only be inhabited by the values from 0 to n-1. For instance, Finite 5 is inhabited by the numbers 0–4, but does not permit any other value. This functionality relies on the DataKinds extension, which allows the use of integers (amongst other things) at the type level. Take a look at the source code of the library if you’re interested in seeing how this works; the most important part is:
-- | Finite number type. #'Finite' n# is inhabited by exactly #n# values. Invariants:
--
-- prop> getFinite x < natVal x
-- prop> getFinite x >= 0
newtype Finite (n :: Nat) = Finite Integer
deriving (Eq, Ord, Generic)
-- | Convert an 'Integer' into a 'Finite', throwing an error if the input is out of bounds.
finite :: KnownNat n => Integer -> Finite n
finite x = result
where
result = if x < natVal result && x >= 0
then Finite x
else error $ "finite: Integer " ++ show x ++ " is not representable in Finite " ++ show (natVal result)
-- | Convert a 'Finite' into the corresponding 'Integer'.
getFinite :: Finite n -> Integer
getFinite (Finite x) = x

haskell type,new type or data for only an upper case char

If i want to make a String but holds only an uppercase character. I know that String is a [Char]. I have tried something like type a = ['A'..'Z'] but it did not work any help?
What you're wanting is dependent types, which Haskell doesn't have. Dependent types are those that depend on values, so using dependent types you could encode at the type level a vector with length 5 as
only5 :: Vector 5 a -> Vector 10 a
only5 vec = concatenate vec vec
Again, Haskell does not have dependent types, but languages like Agda, Coq and Idris do support them. Instead, you could just use a "smart constructor"
module MyModule
( Upper -- export type only, not constructor
, mkUpper -- export the smart constructor
) where
import Data.Char (isUpper)
newtype Upper = Upper String deriving (Eq, Show, Read, Ord)
mkUpper :: String -> Maybe Upper
mkUpper s = if all isUpper s then Just (Upper s) else Nothing
Here the constructor Upper is not exported, just the type, and then users of this module have to use the mkUpper function that safely rejects non-uppercase strings.
For clarification, and to show how awesome dependent types can be, consider the mysterious concatenate function from above. If I were to define this with dependent types, it would actually look something like
concatenate :: Vector n a -> Vector m a -> Vector (n + m) a
concatenate v1 v2 = undefined
Wait, what's arithmetic doing in a type signature? It's actually performing type-system level computations on the values that this type is dependent on. This removes a lot of potential boilerplate in Haskell, and it makes guarantees at compilation time that, e.g., arrays can't have negative length.
Most desires for dependent types can be filled either using smart constructors (see bheklilr's answer), generating Haskell from an external tool (Coq, Isabelle, Inch, etc), or using an exact representation. You probably want the first solution.
To exactly represent just the capitals then you could write a data type that includes a constructor for each letter and conversion to/from strings:
data Capital = CA | CB | CC | CD | CE | CF | CG | CH | CI | CJ | CK | CL | CM | CN | CO | CP | CQ | CR | CS | CT | CU | CV | CW | CX | CY | CZ deriving (Eq, Ord, Enum)
toString :: [Capital] -> String
toString = map (toEnum . (+ (fromEnum 'A')) . fromEnum)
You can even go a step further and allow conversion from string literals, "Anything in quotes", to a type [Capitals] by using the OverloadedStrings extension. Just add to the top of your file {-# LANGUAGE OverloadedStrings, FlexibleInstances #-}, be sure to import Data.String and write the instance:
type Capitals = [Capital]
instance IsString Capitals where
fromString = map (toEnum . (subtract (fromEnum 'A')) . fromEnum) . filter (\x -> 'A' <= x && x <= 'Z')
After that, you can type capitals all you want!
*Main> toString ("jfoeaFJOEW" :: Capitals)
"FJOEW"
*Main>
bheklilr is correct but perhaps for your purposes the following could be OK:
import Data.Char(toUpper)
newtype UpperChar = UpperChar Char
deriving (Show)
upperchar :: Char -> UpperChar
upperchar = UpperChar. toUpper
You can alternatively make UpperChar an alias of Char (use type instead of newtype) which would allow you to forms lists of both Char and UpperChar. The problem with an alias, however, is that you could feed a Char into a function expecting an UpperChar...
One way to do something similar which will work well for the Latin script of your choice but not so well as a fully general solution is to use a custom type to represent upper case letters. Something like this should do the trick:
data UpperChar = A|B|C|D| (fill in the rest) | Y | Z deriving (Enum, Eq, Ord, Show)
newtype UpperString = UpperString [UpperChar]
instance Show UpperString
show (UpperString s) = map show s
The members of this type are not Haskell Strings, but you can convert between them as needed.

Restricting values in type constructors [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to create a type bounded within a certain range
I have the data type:
data Expr = Num Int
| Expression Expr Operator Expr
In the context of the problem, the numbers that (Num Int) will represent are single digit only. Is there a way to ensure that restriction within the type declaration?
Of course we could define a function to test whether the Expr is valid, but it would be nice to have the type system handle it.
You can use an abstract data type with a smart constructor:
newtype Digit = Digit { digitVal :: Int }
deriving (Eq, Ord, Show)
mkDigit :: Int -> Maybe Digit
mkDigit n
| n >= 0 && n < 10 = Just (Digit n)
| otherwise = Nothing
If you put this in another module and don't export the Digit constructor, then client code can't construct values of type Digit outside of the range [0,9], but you have to manually wrap and unwrap it to use it. You could define a Num instance that does modular arithmetic, if that would be helpful; that would also let you use numeric literals to construct Digits. (Similarly for Enum and Bounded.)
However, this doesn't ensure that you never try to create an invalid Digit, just that you never do. If you want more assurance, then the manual solution Jan offers is better, at the cost of being less convenient. (And if you define a Num instance for that Digit type, it will end up just as "unsafe", because you'd be able to write 42 :: Digit thanks to the numeric literal support you'd get.)
(If you don't know what newtype is, it's basically data for data-types with a single, strict field; a newtype wrapper around T will have the same runtime representation as T. It's basically just an optimisation, so you can pretend it says data for the purpose of understanding this.)
Edit: For the more theory-oriented, 100% solution, see the rather cramped comment section of this answer.
Since there are only ten possibilities, you could use Enum to specify all of them.
data Digit = Zero | One | Two deriving (Enum, Show)
Then you'd have to use fromEnum to treat them as numbers.
1 == fromEnum One
Similarly, using toEnum you can get a Digit from a number.
toEnum 2 :: Digit
We can go even further and implement Num.
data Digit = Zero | One | Two deriving (Enum, Show, Eq)
instance Num Digit where
fromInteger x = toEnum (fromInteger x) :: Digit
x + y = toEnum $ fromEnum x + fromEnum y
x * y = toEnum $ fromEnum x * fromEnum y
abs = id
signum _ = 1
Zero + 1 + One == Two

Haskell deriving additional instances for imported datatypes

I'm relatively new to Haskell. I write a clone of the card game uno and i want pretty coloured output of a card. I do
import System.Console.ANSI
which provides
data Color = Black
| Red
| Green
| Yellow
| Blue
| Magenta
| Cyan
| White
deriving (Bounded, Enum, Show)
now i want to add deriving (Ord, Eq) as well, i could write this in the source file of the imported package, but there should be an easier way to do this.
i don't have a clue what keywords to google for or look for in a book.
No need to edit the library. In your source file, state:
instance Eq Color where
x == y = fromEnum x == fromEnum y
instance Ord Color where
compare x y = compare (fromEnum x) (fromEnum y)
Explanation: fromEnum is a function on Enum that returns an int (Black -> 0, Red -> 1, etc.). Integers are obviously equality-comparable and ordered.
Edit: #rampion's version, in the comments, is obviously prettier:
instance Eq Color where
(==) = (==) `on` fromEnum
instance Ord Color where
compare = compare `on` fromEnum

Resources