Mam następujący kod

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

A REPT, próbowałem uzyskać instancję Text typu:

:t something ("hello" :: Text) 

A kompilator narzeka:

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

Domyślnie weźmie to typ String:

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

Jak uzyskać typ Text zamiast String?

5
softshipper 22 luty 2019, 12:36

2 odpowiedzi

Najlepsza odpowiedź

Nie ma nic problematycznego z Twoim kodem. Robiąc coś takiego jak ten, spowodowałby taki błąd:

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

Ale możesz to zrobić dobrze z String:

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

Należy pamiętać, że nawet jeśli twój plik ma w nim OverloadedString, nie zostanie załadowany po załadowaniu tego pliku w rekordzie. Możesz zobaczyć aktualnie załadowane rozszerzenia takie jak:

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

Możesz użyć rozszerzenia OverloadedStrings, aby opatrywać go na Text lub nawet 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

Z powyższym rozszerzeniem ustawionym w REP, Twój kod będzie działał:

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

Rozszerzenie overloadedstrings zwiększa obsługę przeciążonych ciągów. Więcej informacji o tym można znaleźć / A>. Krótkie wyjaśnienie tego: definiując typ, który jest instancją IsString typeClass, możesz oznaczyć go za pośrednictwem dosłownika:

import GHC.Exts (IsString(..))

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

instance IsString MyFancyText where
  fromString str = MyFancyText str

A potem w REP:

λ> let xs = "hello" :: MyFancyText
λ> :t xs
xs :: MyFancyText
6
Sibi 22 luty 2019, 10:25

Musisz także włączyć OverloadedStrings w samym GHCI. Uruchom to w ten sposób:

ghci -XOverloadedStrings file.hs

A potem powinno działać:

> :t something ("hello" :: Text) 
something ("hello" :: Text) :: IO ()
3
Karol Samborski 22 luty 2019, 10:02