如何获取文字类型?

时间:2019-02-22 09:36:51

标签: haskell

我有以下代码

 {-# 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" 

在REPL中,我尝试获取Text类型的实例,如下所示:

:t something ("hello" :: Text) 

编译器抱怨:

<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)

默认情况下,它将采用String类型:

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

如何获取Text类型而不是String类型?

2 个答案:

答案 0 :(得分:6)

您的代码没有任何问题。做这样的事情本身会导致这样的错误:

λ> 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

但是您可以使用String做到这一点:

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

请注意,即使文件扩展名为OverloadedString,当您在repl中加载该文件时也不会加载该文件。您可以看到当前正在加载的扩展名,如下所示:

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

您可以使用OverloadedStrings扩展名将其注释为Text甚至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

在repl中设置上述扩展名后,您的代码将起作用:

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

OverloadedStrings扩展增加了对重载字符串的支持。您可以找到关于here的更多详细信息。简短说明:通过将类型定义为IsString类型类的实例,可以通过String文字来表示它:

import GHC.Exts (IsString(..))

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

instance IsString MyFancyText where
  fromString str = MyFancyText str

然后在REPL中:

λ> let xs = "hello" :: MyFancyText
λ> :t xs
xs :: MyFancyText

答案 1 :(得分:2)

您还需要在ghci本身中启用OverloadedStrings。像这样运行它:

ghci -XOverloadedStrings file.hs

然后它应该起作用:

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