29

This might be a really noobish question, but I can't get past this problem (as I just started learning Haskell).

I have a simple block of code:

module SomeTest where
import Data.Text

str =  replace "ofo" "bar" "ofofo"

If I call this with str, I get:

<interactive>:108:19: error:
* Couldn't match expected type `Text' with actual type `[Char]'
* In the first argument of `Data.Text.replace', namely `"ofo"'
  In the expression: Data.Text.replace "ofo" "bar" "ofofo"
  In an equation for `it': it = Data.Text.replace "ofo" "bar" "ofofo"

<interactive>:108:25: error:
* Couldn't match expected type `Text' with actual type `[Char]'
* In the second argument of `Data.Text.replace', namely `"bar"'
  In the expression: Data.Text.replace "ofo" "bar" "ofofo"
  In an equation for `it': it = Data.Text.replace "ofo" "bar" "ofofo"

<interactive>:108:31: error:
* Couldn't match expected type `Text' with actual type `[Char]'
* In the third argument of `Data.Text.replace', namely `"ofofo"'
  In the expression: Data.Text.replace "ofo" "bar" "ofofo"
  In an equation for `it': it = Data.Text.replace "ofo" "bar" "ofofo"

I don't know why I'm getting this error and how to get pass it. Isn't Text just a synonym for [Char]?

melpomene
  • 84,125
  • 8
  • 85
  • 148
Janez Lukan
  • 1,439
  • 1
  • 12
  • 28
  • No, `Text` is a completely different type. `String` is a synonym for `[Char]`, though. – melpomene Jun 18 '16 at 08:42
  • 3
    Unfortunately, Haskell has several conflicting types for strings of characters. In your case, adding `{-# LANGUAGE OverloadedStrings #-}` as the first line of your program should make it compile. – stholzm Jun 18 '16 at 09:09
  • Thanks, this really worked. Please, make an answer from this comment, and I'll accept it. – Janez Lukan Jun 18 '16 at 09:16

2 Answers2

52

Unfortunately, Haskell has several conflicting types for strings of characters. String literals are usually of type String which is just an alias for [Char]. Because that is an inefficient representation of strings, there are alternatives, like Text.

In your case, adding {-# LANGUAGE OverloadedStrings #-} as the first line of your program will make it compile. Basically your string literals can be of type Text then.

In the case of ghci you can run :set -XOverloadedStrings.

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
stholzm
  • 3,395
  • 19
  • 31
  • 26
    `OverloadedStrings` implicitly turns all string literals `"foo"` into `fromString "foo"`. [`fromString`](http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-String.html#v:fromString) is a method that can convert from `String` to any instance of the `IsString` class, such as `Text`. – melpomene Jun 18 '16 at 09:35
  • 8
    While this will work, you might also get more complicated errors about ambiguous types because GHC can't determine which instance of "IsString" should be used. These can generally be resolved by changing "some text" into ("some text" :: Text). – Paul Johnson Jun 18 '16 at 09:44
  • Thanks for improving my answer! Perhaps you want to write your own in greater detail? This is probably a common source of confusion for Haskell newbies. – stholzm Jun 18 '16 at 10:23
  • Thanks, melpomene. In my case, adding the language extension didn't help because was `show` returning `String`. Thanks to your comment, I knew passing it through `fromString` would fix it. – alltom Oct 03 '16 at 05:56
3

In my case I had code that was doing concatenation of a String and Text value:

"cd " ++ stackProjectLocation

"cd " was being of type Text because of using {-# LANGUAGE OverloadedStrings #-}

And stackProjectLocation was a String

The solution was to use (<>) :: Semigroup a => a -> a -> a:

"cd " <> stackProjectLocation
Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169