Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the text type?

Tags:

haskell

I've the following code

 {-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleInstances #-}

module Lib where

import Data.Text (Text)

class DoSomething a where
  something :: a -> IO ()

instance DoSomething String where
  something _ = putStrLn "String"


instance DoSomething Text where
  something _ = putStrLn "Text" 

And in REPL, I tried to get an instance of Text type as the following:

:t something ("hello" :: Text) 

and the compiler complains:

<interactive>:1:12: error:
    • Couldn't match expected type ‘Text’ with actual type ‘[Char]’
    • In the first argument of ‘something’, namely ‘("hello" :: Text)’
      In the expression: something ("hello" :: Text)

By default, it will take the String type :

:t something "hello"
something "hello" :: IO ()

How to get Text type instead of String type?

like image 524
softshipper Avatar asked Feb 22 '19 09:02

softshipper


1 Answers

There is nothing problematic with your code. Doing something like this itself would result in such an error:

λ> import Data.Text
λ> let t = "hello world" :: Text

<interactive>:11:9: error:
    • Couldn't match expected type ‘Text’ with actual type ‘[Char]’
    • In the expression: "hello world" :: Text
      In an equation for ‘t’: t = "hello world" :: Text

But you can do that fine with String:

λ> let t = "hello world" :: String

Note that even though your file has OverloadedString extension in it, it won't be loaded when you load that file in the repl. You can see the currently loaded extensions like this:

λ> :show language
base language is: Haskell2010
with the following modifiers:
  -XNoDatatypeContexts
  -XNondecreasingIndentation

You can use the OverloadedStrings extension to annotate it to Text or even ByteString.

λ> :set -XOverloadedStrings
λ> :show language
base language is: Haskell2010
with the following modifiers:
  -XNoDatatypeContexts
  -XNondecreasingIndentation
  -XOverloadedStrings
λ> let t = "hello" :: Text
λ> import Data.ByteString
λ> let t = "hello" :: ByteString

With the above extension set in repl, your code will work:

λ> :t something ("hello" :: Text) 
something ("hello" :: Text) :: IO ()
λ> something ("hello" :: Text) 
Text

The OverloadedStrings extension adds support for overloaded strings. You can find more detabils about it here. Short explanation of it: By definining your type to be an instance of IsString typeclass, you can denote it via String literal:

import GHC.Exts (IsString(..))

data MyFancyText =
  MyFancyText String
  deriving (Show, Eq, Ord)

instance IsString MyFancyText where
  fromString str = MyFancyText str

And then in REPL:

λ> let xs = "hello" :: MyFancyText
λ> :t xs
xs :: MyFancyText
like image 187
Sibi Avatar answered Sep 21 '22 11:09

Sibi