Haskell:为什么GHC为main方法推断的类型不太完整?
例如,以Don Stewart在回答某些堆栈溢出问题时编写的代码为例:Haskell:为什么GHC为main方法推断的类型不太完整?,haskell,type-inference,ghci,Haskell,Type Inference,Ghci,例如,以Don Stewart在回答某些堆栈溢出问题时编写的代码为例: import Control.Monad import qualified Data.HashTable as H import System.Environment main = do [size] <- fmap (fmap read) getArgs m <- H.new (==) H.hashInt forM_ [1..size] $ \n -> H.insert m n n v
import Control.Monad
import qualified Data.HashTable as H
import System.Environment
main = do
[size] <- fmap (fmap read) getArgs
m <- H.new (==) H.hashInt
forM_ [1..size] $ \n -> H.insert m n n
v <- H.lookup m 100
print v
为什么main的类型签名不反映正在调用getArgs::IO[String]
的事实
运行二进制文件时,可以给出一个参数。
145
只返回100
但在GHCi中,您不能:
main 145
给出错误。如何在GHCi中运行此程序并给出参数。main的类型是其最终表达式的类型print
生成IO()
,这就是main
的类型。中间类型是不相关的,因为(>>=)
只传播monad
(>>=) :: Monad m => m a -> (a -> m b) -> m b
a
不会出现在结果类型中(mb
)
至于在GHCi中运行程序,请查看
:main
命令。您想:设置参数的值。例如:
Prelude> import System.Environment
Prelude System.Environment> getArgs
[]
Prelude System.Environment> :set args ["foo","bar"]
Prelude System.Envrionment> getArgs
["foo","bar"]
至于类型签名问题,这里的main类型由print v
确定。之前的所有内容都将通过>
操作员忽略。谢谢。我知道do是>>=的语法糖,它的签名是(>>=)::(Monad m)=>ma->(a->mb)->mb。但是,即使使用了一元运算,编译器也不可能在计算中使用类型签名为getArgs::IO[String]的getArgs这一事实吗?并提供更有意义的类型签名?或者这根本不可能?在哈斯克尔就不可能。。我也不清楚这样做除了已有的价值之外还有什么价值(IO
)。这些信息对编译器很有帮助,但在其他方面则不然。除非你真正想的是把IO
拆分,这是一个长期讨论的话题,归结起来是一个逻辑上的噩梦。如果这让你感到困扰,那么把你所有的代码放在一个mainX:::[String]->IO()
函数中,让main=getArgs>=mainX
Prelude> import System.Environment
Prelude System.Environment> getArgs
[]
Prelude System.Environment> :set args ["foo","bar"]
Prelude System.Envrionment> getArgs
["foo","bar"]