我有以下代码
{-# 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
类型?
答案 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 ()