Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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 lambda表达式的推断类型_Haskell_Lambda_Types_Expression_Type Inference - Fatal编程技术网

Haskell lambda表达式的推断类型

Haskell lambda表达式的推断类型,haskell,lambda,types,expression,type-inference,Haskell,Lambda,Types,Expression,Type Inference,给定具有以下类型的函数a: a::x->Bool 以及以下类型的另一个函数b: b::Bool->y 我试图找出推断以下函数类型的步骤: c=\d->dab 请有人解释一下如何做,而不仅仅是通过ghc的:type函数? 谢谢c=\d->dab的类型将是c:((x->Bool)->(Bool->y)->t)->t 其中,d是一个函数,它接受a(x->Bool)和a(Bool->y),并返回类型为t的值 因此c是一个函数,它接受d类型的函数,并返回t类型的值 如果您的意思是c=\d->d(ab)类型

给定具有以下类型的函数a:
a::x->Bool

以及以下类型的另一个函数b:
b::Bool->y

我试图找出推断以下函数类型的步骤:
c=\d->dab

请有人解释一下如何做,而不仅仅是通过ghc的:type函数?
谢谢

c=\d->dab
的类型将是
c:((x->Bool)->(Bool->y)->t)->t

其中,
d
是一个函数,它接受a
(x->Bool)
和a
(Bool->y)
,并返回类型为
t
的值

因此
c
是一个函数,它接受
d
类型的函数,并返回
t
类型的值

如果您的意思是
c=\d->d(ab)
类型将是
c::(Bool->y)->y

一些额外的解释。

要知道
c
我们必须首先知道
d
做什么,所以我们看
c=\d->dab

我们看到
\d->dab
,所以我们知道
d
的第一个参数是类型为
(x->Bool)
的函数
a
。我们还知道
d
的第二个参数,它是类型为
(Bool->y)
的函数
b
。但我们不知道它会返回什么,因为这是Haskell,它必须返回一些东西,所以我将以未知类型编写
t
。 所以
d
就是
d::a->b->t

替换为
a
b
类型,得到
d:(x->Bool)->(Bool->y)->t

现在对于
c
c
是一个lambda,它接受一个我们可以推断为
d
类型的值,并返回其输出。所以我们得到
c::d->(d的输出)


替换为
d
的类型,我们得到
c:((x->Bool)->(Bool->y)->t)->t

另一种方法是使用类型签名,以确保在避免使用
:t
的同时获得特定lambda表达式的预期类型签名

在这种情况下,
x
是不受限制的

idFunction = \x -> x
如果我们想限制到一个特定的类型,我们可以直接注释
x
。(这需要在GHCi中设置-XScopedTypeVariables,或者在文件中设置
{-#语言范围的TypeVariables}

或者我们可以添加一个类型签名

idFunction :: Int -> Int
idFunction = \x -> x
在您的示例中,只有类型签名,但没有函数体。让我们添加一些简单的函数体,这样我们就可以对编译器做一些事情,然后我们将尝试向
c
添加一个类型签名,以确认我们对类型应该是什么的看法。我们将从错误的类型签名开始

a :: Int -> Bool
a x = x > 0

b :: Bool -> String
b y = show y

c :: ((Bool -> Bool) -> (Bool -> Bool) -> t) -> t
c = \d -> d a b
编译器将在
c
中找到一些错误:

<interactive>:10:17: error:
    • Couldn't match type ‘Bool’ with ‘Int’
      Expected type: Bool -> Bool
        Actual type: Int -> Bool
    • In the first argument of ‘d’, namely ‘a’
      In the expression: d a b
      In the expression: \ d -> d a b

<interactive>:10:19: error:
    • Couldn't match type ‘[Char]’ with ‘Bool’
      Expected type: Bool -> Bool
        Actual type: Bool -> String
    • In the second argument of ‘d’, namely ‘b’
      In the expression: d a b
      In the expression: \ d -> d a b

通常没有任何理由避免
:t
。当您在GHCi中工作时,它是一个非常好的工具,但是当您在库中构建复杂函数时,您不必访问
:t
,因此另一种方法是测试不同的类型签名并查看编译器的反应。

我的意思是
c=\d->dab
,您介意再解释一下吗?:)我想尽我所能解释一下,我希望这能有所帮助。谢谢你,我真的很感激额外的解释:)如果你知道a和b的身体功能,你会如何处理它,其中:a=a和b=b这些只是
id
函数,你会有一个类似
((x->x)->(y->y)->t)->/code>的类型签名。
<interactive>:10:17: error:
    • Couldn't match type ‘Bool’ with ‘Int’
      Expected type: Bool -> Bool
        Actual type: Int -> Bool
    • In the first argument of ‘d’, namely ‘a’
      In the expression: d a b
      In the expression: \ d -> d a b

<interactive>:10:19: error:
    • Couldn't match type ‘[Char]’ with ‘Bool’
      Expected type: Bool -> Bool
        Actual type: Bool -> String
    • In the second argument of ‘d’, namely ‘b’
      In the expression: d a b
      In the expression: \ d -> d a b
c :: ((Int -> Bool) -> (Bool -> String) -> t) -> t
c = \d -> d a b