0
votes

Sorry if this is stupid question - I am constantly getting error and can not figure it out. My code below:

data Health = Health [String]

let health = Health ["<3","<3","<3"]

showHealth :: [Health] -> String 
showHealth [] = ""
showHealth (x:xs) = "" ++ (showSingleHealth x) ++ (showHealth xs)


showSingleHealth :: Health -> String 
showSingleHealth (Health point) = point

And error I am getting is on "showSingleHealth", error say - Couldn't match type ‘[Char]’ with ‘Char’ Expected type: String Actual type: [String] . In the expression: point In an equation for ‘showSingleHealth’: showSingleHealth (Health point) = point

1
Remove the let. This is used in a do block, or in an expression with let ... in ..., but not in a declaration. - Willem Van Onsem
It is used in a do, it's a small game that I am trying to implement, just dragged code parts for this exact part that I am having issue with :) - Human Code
The pattern Health point binds point to a list of Strings, not a single String. What is showSingleHealth heath supposed to return? What argument do you intend to pass to showHealth? I wonder if all you really want is showHealth = concat, to turn ["<3", "<3", "<3"] into "<3<3<3". - chepner

1 Answers

3
votes

You should remove the let. A let is used in a do block, and a let … in … in an expression, but not in a declaration.

You thus can implement this with:

data Health = Health [String]

health = Health ["<3","<3","<3"]

showHealth :: [Health] -> String 
showHealth [] = ""
showHealth (x:xs) = "" ++ (showSingleHealth x) ++ (showHealth xs)


showSingleHealth :: Health -> String 
showSingleHealth (Health point) = point

But this does not resolve all the problems, since showSingleHealth should return a String, but point is a list of strings. You thus can for example concatenate the health items with concat :: Foldable f => f [a] -> [a]:

showSingleHealth :: Health -> String
showSingleHealth (Health point) = concat point

Finally showHealth can be implemented in a more clean manner with concatMap :: Foldable t => (a -> [b]) -> t a -> [b]:

showHealth :: [Health] -> String 
showHealth = concatMap showSingleHealth

That being said, it might make more sense to let Health only wrap a single String, not a list of Strings, or even better, an Int for example, and repeat a string part with replicate :: Int -> a -> [a].