该错误中IHaskellPrelude来自何处?

时间:2019-04-24 13:53:45

标签: haskell jupyter ihaskell haskell-prelude

我正在使用ihaskell jupyter笔记本工作,所以我知道明显的答案。

但是我还使用了从Data.List的显式导入,它显示了此错误

import qualified Data.List as L

因此,我实际上对涉及引用IHaskellPrelude的行感到困惑 我从Data.List显式导入的内容,这不是先例。 (这是this one之后的一个更具体的问题)

我的错误消息:

<interactive>:14:35: error:
    • Couldn't match type ‘Char’ with ‘String’
      Expected type: String -> String
        Actual type: String -> Char
    • In the ‘fieldLabelModifier’ field of a record
      In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}’
      In the expression: genericToJSON defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}
<interactive>:14:47: error:
    • Couldn't match type ‘String’ with ‘Char’
      Expected type: String -> Char
        Actual type: String -> String
    • In the second argument of ‘(.)’, namely ‘IHaskellPrelude.drop 3’
      In the ‘fieldLabelModifier’ field of a record
      In the first argument of ‘genericToJSON’, namely ‘defaultOptions {fieldLabelModifier = Data.Char.toLower . IHaskellPrelude.drop 3}’

看到有关fieldLabelModifier的那一行吗?它调用IHaskellPrelude.drop。但是,如果您看下面,我的代码将调用L.drop:

完整代码:

{-# LANGUAGE DeriveGeneric,  OverloadedStrings, RankNTypes, KindSignatures #-}
:ext DeriveGeneric OverloadedStrings FlexibleContexts RankNTypes KindSignatures DataKinds

-- stack overflow question
import GHC.Generics
import Data.Aeson 
import Data.Aeson.Encode.Pretty 
import Data.Time
-- every dumb library working with any text in haskell requires
import Data.Text as T
import Text.Show.Pretty
import Data.Char(toLower)
import qualified Data.List as L
import qualified Data.Char as C
import Data.ByteString as BS
import Data.Aeson.Text (encodeToLazyText)
import Data.Text.Lazy.IO as I
--
import Text.Regex.PCRE
(.=) = (Data.Aeson..=)

type Code = Text
type Value = Float

-- currency parser
-- Sample
currency = "100.01"

-- -- Value part
vparse :: T.Text -> Float
vparse raw = (read ((T.unpack raw) =~ ("[\\d].*") :: String) :: Float)


data R3 = R3 { recCode :: Code 
             , recValue :: Value} deriving (Show, Generic)


makeR3 rawcode rawval = R3 code value where
                                     code = rawcode
                                     value = vparse rawval


instance ToJSON R3 where
  toJSON = genericToJSON defaultOptions {
             fieldLabelModifier = C.toLower . L.drop 3 }
-- this says L.drop not prelude!  


instance FromJSON R3 where
  parseJSON = withObject "R3" $ \r ->
      R3 <$> r .: "code"
         <*> r .: "value"

r3 = makeR3 "TD" "100.42"
as_json = encode r3


main = do
    let out = encodeToLazyText r3
    I.putStrLn out
    I.writeFile "./so2.json" out
    return ()

main

我正在一个新的会话中工作,新的终端,只运行了这个。我不明白为什么向我引用的错误消息使用的是源自IHaskellPrelude.drop的函数,而不是使用我明确调用的L.drop。

更新

根据尝试中的建议,

instance ToJSON R3 where
  toJSON = genericToJSON defaultOptions {
             fieldLabelModifier = map toLower . L.drop 3 }

我得到:

<interactive>:14:35: error:
    Ambiguous occurrence ‘map’
    It could refer to either ‘BS.map’, imported from ‘Data.ByteString’
                          or ‘T.map’, imported from ‘Data.Text’
                          or ‘IHaskellPrelude.map’, imported from ‘Prelude’ (and originally defined in ‘GHC.Base’)
<interactive>:14:39: error:
    Ambiguous occurrence ‘toLower’
    It could refer to either ‘Data.Char.toLower’, imported from ‘Data.Char’ at <interactive>:1:18-24 (and originally defined in ‘GHC.Unicode’)
                          or ‘T.toLower’, imported from ‘Data.Text’

以下哪种组合与Prelude要求的兼容?

1 个答案:

答案 0 :(得分:1)

IHaskellPrelude.drop还是Data.List.drop都没关系:它们是同一件事。标准的Prelude和IHaskell都可以简单地重新导出列表drop函数。 GHC注意到了这一点,因此显然决定通知您更多“基本”的导入路径,即前言中的一种。 (我不知道试探法是如何工作的,但是通常GHC非常擅长为绑定显示最方便的导入限定符名称。)

问题在于您的toJSON类型不正确,因为toLower仅适用于Char,而不适用于String。可以使用map toLower轻松解决。