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

发布于 2024-11-15 20:16:59 字数 665 浏览 5 评论 0原文

例如,采用 Don Stewart 在回答某些 Stack Overflow 问题时编写的代码:

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

在 GHCi 中加载它。

:t getArgs ---> getArgs :: IO [String]
:t main    ---> main :: IO ()

为什么 main 的类型签名没有反映出正在调用 getArgs :: IO [String] 的事实?

当您运行二进制文件时,您可以给出一个参数。 <代码><程序>; 145 返回仅 100 但在 GHCi 中,您不能:main 145 给出错误。你如何在 GHCi 中运行这个程序并给出一个参数。

For example, take the code written by Don Stewart in reply to some Stack Overflow question:

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

Load it in GHCi.

:t getArgs ---> getArgs :: IO [String]
:t main    ---> main :: IO ()

Why doesn't the type signature of main reflect the fact that getArgs :: IO [String] is being called?

When you run the binary you can give an argument.
<prog> 145 returns Just 100
But in GHCi, you cannot: main 145 gives error. How do you run this program in GHCi and give an argument.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

断舍离 2024-11-22 20:16:59

main 的类型是其最终表达式的类型; print 生成 IO (),因此这就是 main 的类型。中间类型不相关,因为 (>>=) 不会传播除 monad 之外的任何内容。

(>>=) :: Monad m => m a -> (a -> m b) -> m b

a 不会出现在结果类型 (m b) 中。

至于在 GHCi 中运行程序,请查看 :main 命令。

The type of main is that of its final expression; print produces IO (), so that's the type of main. Intermediate types are not relevant, as (>>=) doesn't propagate anything other than the monad.

(>>=) :: Monad m => m a -> (a -> m b) -> m b

a doesn't appear in the result type (m b).

As for running your program in GHCi, take a look at the :main command.

暮年慕年 2024-11-22 20:16:59

您想要 :set args 的值。例如:

Prelude> import System.Environment
Prelude System.Environment> getArgs
[]
Prelude System.Environment> :set args ["foo","bar"]
Prelude System.Envrionment> getArgs
["foo","bar"]

关于类型签名问题,这里的main的类型是由print v决定的。通过 >> 运算符忽略它之前的所有内容。

You want to :set the value of args. For example:

Prelude> import System.Environment
Prelude System.Environment> getArgs
[]
Prelude System.Environment> :set args ["foo","bar"]
Prelude System.Envrionment> getArgs
["foo","bar"]

As for the type signature issue, the type of main here is determined by print v. Everything else before it is ignored via the >> operator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文