当问GHCI
类型时,我倾向于远离理想类型(例如,不完全是放入我的函数签名或在语法上类似于库组合器的类型)。
*Main Control.Monad.Shell> :t script
script :: Script f -> text-1.2.1.3:Data.Text.Internal.Lazy.Text
*Main Control.Monad.Shell> :t cmd "echo" "foo"
cmd "echo" "foo" :: CmdParams t => t
为什么GHCI
显示隐藏的内部类型(甚至是包版本),但在第二种情况下,当包(可能)设计为使用别名时,它是一般类型?
基本上避免使用非平凡类型和查找文档的类型推理器是一种好习惯吗?
更受欢迎"库示例:
*Main Control.Lens> :t _2
_2 :: (Functor f, Field2 s t a b) => (a -> f b) -> s -> f t
*Main Control.Lens> :t over
over :: Profunctor p => Setting p s t a b -> p a b -> s -> t
*Main Control.Lens> :t over _2
over _2 :: Field2 s t a b => (a -> b) -> s -> t
答案 0 :(得分:4)
ghci如何描述类型取决于:
在这种情况下,您将看到内部类型而不是预期的导出类型:
=== file B.hs ===
module B (hello) where
import Data.Text
hello = pack "Hello, world"
=== file A.hs ===
module A where
import B
然后运行ghci A.hs
,命令:t hello
将报告:
ghci> :t hello
hello :: Data.Text.Internal.Text
但是,如果模块A导入Data.Text:
module A where
import B
import Data.Text
然后ghci响应类型查询:
ghci> :t hello
hello :: Text
对于出现在类型名称中的特定包名称,如果未在您的cabal文件中明确提及text
作为依赖项,但是从另一个中导入Data.Text值,则可能会发生这种情况。封装
例如,假设上面的模块B是hello
包的一部分,而模块A是单独包的一部分,比如uses-hello
。
让我们说uses-hello.cabal
文件如下:
=== file uses-hello.cabal ===
...
library:
exposed-modules: A
build-depends: base, hello
...
请注意,uses-hello
不列出text
作为包依赖项,但它可以通过从{{1}导入B
来使用Text值包。如果您在hello
包中运行cabal repl
,您将获得如下输出:
uses-hello