Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:为什么GHC为main方法推断的类型不太完整?_Haskell_Type Inference_Ghci - Fatal编程技术网

Haskell:为什么GHC为main方法推断的类型不太完整?

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

例如,以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 <- 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"]