Sudhanshu
Sudhanshu

Reputation: 125

Error while passing strings in functions in Haskell

So I tried the following code in haskell where I try to detect if the user has entered a "no" or "No" in the string. Also I tried replacing [[Char]] with Strings but it gives compilation errors.

  wantGifts :: [[Char]] -> [[Char]]
  wantGifts st = [if (x == "No" || x== "no") then "No gifts given" else "But why" | x <-  st, x == head st]

The above code compiles but when I pass a string to it, it returns an error message:

*Main> wantGifts "no I dont"

<interactive>:8:11:
    Couldn't match type ‘Char’ with ‘[Char]’
    Expected type: [[Char]]
      Actual type: [Char]
    In the first argument of ‘wantGifts’, namely ‘"no I dont"’
    In the expression: wantGifts "no I dont"
    In an equation for ‘it’: it = wantGifts "no I dont"

Upvotes: 0

Views: 1280

Answers (2)

jkeuhlen
jkeuhlen

Reputation: 4517

Look closely at the type of wantGifts, it requires a List of List of Chars. But "no I dont" is of type String which is just [Char]. With your current construction, you have to use:

wantGifts ["no I dont"]

There are several ways to improve this, best is to use Text.

import Data.Text (Text)
import qualified Data.Text as T
wantGifts :: Text -> Text 
wantGifts txt = if (T.isInfixOf "no" . T.toLower) txt then "No gifts given" else "But why"

Upvotes: 2

Chad Gilbert
Chad Gilbert

Reputation: 36375

You have defined wantGifts as taking a list of strings. [[Char]] is equivalent to [String]. In the REPL, you are passing it a single string.

If you instead did this, it would compile:

wantGifts ["no I dont"]

However, I have a hunch this isn't what you want.

If you were trying to detect whether the word "no" was anywhere in the string, you could use the words function:

containsNo :: String -> Bool
containsNo = any (\w -> w == "no" || w == "No") . words

Upvotes: 2

Related Questions