I'm still very new to Haskell, and I'm curious as to how I would merge two Hand's together, so that, the first hand is placed on top of the second hand. I want it to be an infix operator, namely (<+). Here's some code to assist you. I keep getting an error saying "The type signature for ‘<+’ lacks an accompanying binding".
data Rank = Numeric Integer | Jack | Queen | King | Ace
data Suit = Hearts | Spades | Diamonds | Clubs
data Card = Card Rank Suit
data Hand = Empty | Add Card Hand
(<+) :: Hand -> Hand -> Hand
h1 (<+) h2 = undefined
Many thanks in advance for any advice given.
The definition should either be
h1 <+ h2 = undefined
or
(<+) h1 h2 = undefined
You are currently trying to use a function name as an infix operator.
Related
I'm still doing the exercise from the book and the one exercise says that I should create a function: value :: Hand -> Int, which returns the value of the hand.
My code so far looks like this:
data Hand = PairOf Rank | ThreeOf1 Rank | ThreeOf2 Suit
value: Hand -> Int
otherwise = 0
--
I now have another problem, because I don't know how to describe "Nothing".
Nothing is described here as a possible hand combination in which Pair, ThreeOf1 and ThreeOf2 do not occur.
Would otherwise = 0 work or doesn't that make much sense?
Thanks again for the suggestions, I corrected them! Thanks also in advance for explanations and help.
otherwise won't work here. What you want is an irrefutable pattern that will match anything, and further since you don't care what gets matched, you specifically want the pattern _:
value :: Hand -> Int
value (PairOf r1) = 1
value (ThreeOf r1) = 2
value (Flush s1) = 3
value _ = 0
Since you don't care about what kind of pair, etc you get, you can also use _ in the other cases:
value :: Hand -> Int
value (PairOf _) = 1
value (ThreeOf _) = 2
value (Flush _) = 3
value _ = 0
If you wanted to match Nothing (or whatever name you come up with that doesn't conflict with the Maybe constructor) specifically, it's just
value Nothing = 0
One of the problems you might be having is that there is no Nothing.
Here's the full type of Hands for holdem:
data HandRank
= HighCard Rank Rank Rank Rank Rank
| OnePair Rank Rank Rank Rank
| TwoPair Rank Rank Rank
| ThreeOfAKind Rank Rank Rank
| Straight Rank
| Flush Rank Rank Rank Rank Rank
| FullHouse Rank Rank
| FourOfAKind Rank Rank
| StraightFlush Rank
deriving (Eq, Ord, Show, Generic)
The extra ranks in the data type are there to distinguish hands, so a pair of aces with a King & Queen kicker beats a pair of aces with a King & Jack kicker. But otherwise, it's the same as your setup.
Once you have a complete transformation from a set of cards to a hand value, there is no nothing. What you might be thinking of as nothing is the HighHand line in the sum type. If your context is that's it for possible hands, then I would add a NoValue to the Hand sum type, as better than outputting a Maybe Hand.
Using the wild cards otherwise _ or value _ introduces a chance of a bug because you might forget about coding up a full house, say, and your existing function would work. If you forget to code one of the sum types, and you don't have a match-any pattern, the compiler will complain. Providing the compiler with all branches of a sum type is also a hot development area of GHC, and it will be fast.
I'm new to Haskell and code in general and while trying to write a script that shows which of two numbers is smaller to practise using guards i got stuck with the "parse error on input ‘|’" error.
I read about using "let" somehow but I haven't been able to figure it out. How do I get past this error?
smallest a b = | a >= b = b
| a <= b = a
I'm posting this answer to clarify that you do need the equal sign; but you need one for each case, whereas you essentially duplicated it:
-- +--- this is the equal sign (one per case)
-- |
-- +----------|--- which you are duplicating here
-- | |
-- v v
smallest a b = | a >= b = b
| a <= b = a
that's the reason why the suggested code works.
By the way, the indentation is important, but you can write that snippet on 2 lines rather than 3,
smallest a b | a >= b = b
| otherwise = a
though it does not improve readability, and actually decreseas it if the part before the first | is long.
By the way, as far as I remember, otherwise is truly just a synonym for True (well, the former is a function, and the latter a value constructor, but I guess this makes little difference, as the former is like a 0-arguments function that generates the latter, so they are fundamentally synonyms).
When using guards, you don't need the equals sign. You can simply do this:
smallest a b
| a >= b = b
| otherwise = a
Note the indentation here. Also, since your first condition takes care of both the greater than and equal cases, you can simply use "otherwise" instead of explicitly stating the remaining case.
I have defined a data type as follows in Haskell,
data Numbers = "1" | "2" | "3" | "4" | "5"
I want to write a function which will give me the next number if given a number, except if I give it 4(I do not want it to give me 5 then).
next :: Numbers -> Numbers
next number = .....
I am a bit lost on how I can do this. Any suggestions?
You're probably looking for pattern matching syntax.
If you want to go for a more advanced solution, look into deriving Enum and the succ method
i am new to Haskell and probably missing something really basic here, but i am not able to re-use same value constructor among different data types.
data Colour = Red | Pink | Orange | Yellow
data Fruit = Apple | Orange | Banana
This produces error saying
Multiple declarations of ‘Orange’
Not sure why this isn't allowed, i have been using OCaml before learning Haskell and was able to define types like this
As a quick exercise try just defining one of your data types and then opening up GHCi to inspect it.
data Colour = Red | Pink | Orange | Yellow
If you use :t in GHCi, it will tell you the type of anything.
> :t Red
Red :: Colour
> :t Orange
Orange :: Colour
So this tells you that your data constructor Orange is really just a function that takes no arguments and produces a value of type Colour.
So what happens if you add a duplicate declaration?
data Colour = Red | Pink | Orange | Yellow
data Fruit = Apple | Orange | Banana
Now you have defined a function Orange that takes no arguments and produces a value of type Colour or a value of type Fruit. This won't work at all! It would be the same as defining your own custom function foo and giving it multiple type signatures:
foo :: Int
foo :: String
foo = "6"
Which obviously doesn't work either.
To get around this, you can define each data type in its own module, and use a qualified import to scope them correctly:
import qualified Colour as C -- Module Colour.hs
import qualified Fruit as F -- Module Fruit.hs
orange1 = C.Orange :: C.Colour
orange2 = F.Orange :: F.Fruit
Now, you might be thinking "The compiler is smart, it should know what Orange I'm talking about when I'm using it." and you'd be partially right. There is an ongoing effort to bring Overloaded or Duplicate record fields into Haskell. There are various other questions of that ilk already defined here, but I'll list a few
references for further reading.
Why DuplicateRecordFields cannot have type inference?
https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst
https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields
There is no particular reason, that is how language was designed. I think the idea was to make sure compiler can infer type for as many expressions as possible. Note that if language will allow to reuse constructors, then you'll have to specify type for show Orange expression - compiler can't infer it anymore. Though now a lot of people don't take this reason seriously, and a lot of modern language extentions do break compiler's ability to infer types for many expressions. So I guess in few years you'll find that your example works already :)
This is the question from my exam practice paper:
The following table gives the names, grades and age of people employed by a
company:
Name Grade Age
Able Director 47
Baker Manager 38
Charles Trainee 19
Dunn Director 50
Egglestone Manager 42
i. Define a Haskell type suitable for representing the information in such a
table [10%]
A function avAge is required to find the average age of people in a given grade,
for instance in the example the average age of managers is 40. Give three
alternative Haskell definitions for this function:
ii. using explicit recursion, [20%]
iii. using mapping functions, [20%]
iv. using list comprehensions. [20%]
The table isn't very clear as I couldn't paste the proper table but you can basically see there are 3 columns and multiple rows, one for name, one for grade, one for age. So as you can see the first question "i" is to define a haskell type that is suitable for representing an information in such a table. Keep in my that the real table has lines of course.
So how do I define a function to do this? Does define a function mean e.g. "[String] -> String -> Int" or I have to write up a function that does something?
Finally, about the avAGe to find the average age of people what are the ideas behind doing it with mapping functions? I have planned out for explicit recursion but I'm really struggling to fit mapping functions (map, foldr, filter, etc) to this.
A suitable type would be one where each row has a data type and maybe you can use an existing collection type for holding multiple rows. To start you off:
data Entry = Entry __________ deriving (Eq, Show)
type Entries = __________
So what should go in the blank? It'll need to be able to hold a name, a grade, and an age. For Entries, you should be able to use a built-in type to store all these rows, presumably in order.
Are the grades from a fixed number of valid values? Then you might consider using an ADT to represent them:
data Grade
= Trainee
| Manager
| Director
-- | AnyOtherNameYouNeed
deriving (Eq, Show)
If not, then you can just use Strings, but I would still give them a name:
type Grade = String
So now that you have your types set up, you can work on the implementations of avAge. You need explicit recursion, mapping, and list comprehension. The function needs to take Entries and a Grade and return an average of the ages that match that Grade, so the type signature should probably be
avAgeRec :: Entries -> Grade -> Double
avAgeRec entries grade = __________
avAgeMap :: Entries -> Grade -> Double
avAgeMap entries grade = __________
avAgeComp :: Entries -> Grade -> Double
avAgeComp entries grade = __________
This should help you get started, I just don't want to give you the answers since this is a study problem, and it's always better to come up with the answers yourself =)
So now you have
type Grade = String
type Entry = (String, Grade, Int)
type Entries = [Entry]
And with a little filled in from the comments below:
avAgeRec :: Entries -> Grade -> Double
avAgeRec entries grade = __________
avAgeMap :: Entries -> Grade -> Double
avAgeMap entries grade = <calculate average> $ map <get ages> $ filter <by grade> entries
avAgeComp :: Entries -> Grade -> Double
avAgeComp entries grade = __________
Can you get a few more of the blanks filled in now?