评估“main = return(getChar,getChar)”

时间:2012-05-13 00:28:59

标签: haskell

对不起,我说英语不好。

让我们看下面的代码。

main = getChar

首先,将评估main,它的值是“getChar”,但编译器不知道“getChar”值,因此编译器将评估“getChar”以计算“getChar”值,因此,getChar将被执行

实际上当我测试上面的代码时。 “getChar被执行。

让我们看看下面的代码。

main = return (getChar, getChar)

首先,主要评估,它的值是return(undefined,undefined) - > IO(未定义,未定义),因此前置将评估IO(未定义,未定义)以打印该值。所以将对两个getChar中的一个进行评估。

但是,当我测试上面的代码时,没有评估两个getChar。我不明白为什么两个getChar都没有被评估。

2 个答案:

答案 0 :(得分:4)

您必须实际执行monadic操作,然后返回执行结果。

func = do
    a <- getChar
    b <- getChar
    return  (a,b)

您目前正在做的事情就像C声明:

void main(char &a, char &b)
{
    a = getchar;
    b = getchar;
}

与你真正想要的相反:

void main(char &a, char &b)
{
    a = getchar();
    b = getchar();
}

答案 1 :(得分:0)

  

“我想知道为什么两个getChar都没有被评估”

首先,用英语,如逻辑或数学或haskell,(不是(不是p))== p,因此你的问题是:

  

我想知道为什么要对这两个getChars进行评估。

令人困惑,因为我打赌他们都不会被评估。

您的main函数计算IO a的值,然后将评估类型为a的IO内的值。在您的情况下,a是(IO Char,IO Char)。因为Haskell是一种非严格的语言,所以评估元组只意味着构造元组。这不包括对元组组件的评估。例如:

fst (42, 7 `quot` 0 :: Int)

不会因为零错误而中止。 因此我们有:

(getChar, getChar) 

是一个包含2个未评估值的元组。 但即使评估了这些值,我们也有2个IO Char类型的值。这样的值可以看作是在IO monad中执行时返回Char的行为。

因此,不仅没有评估你的元组组件,它们也不会在IO monad中执行。

要实现这一点,您可以将带有两个动作的元组传递给另一个动作:

executeBoth (a,b) = do
    ra <- a
    rb <- b
    return (ra, rb)

现在,去检查一下executeBoth的类型,你可能会看到这一点。