首页 文章

传递函数到函数生成无限类型

提问于
浏览
0

我做了一个错误包并写了这样的函数:

Prelude> doWork f x = f f x

我有一个编译器错误:

<interactive>:3:16: error:
    • Occurs check: cannot construct the infinite type:
        t ~ t -> t1 -> t2
    • In the first argument of ‘f’, namely ‘f’
      In the expression: f f x
      In an equation for ‘doWork’: doWork f x = f f x
    • Relevant bindings include
        x :: t1 (bound at <interactive>:3:10)
        f :: t -> t1 -> t2 (bound at <interactive>:3:8)
        doWork :: (t -> t1 -> t2) -> t1 -> t2 (bound at <interactive>:3:1)

我想知道,为什么应用 f 来参数 f 生成无限类型?这是递归吗?

正确的代码是:

Prelude> doWork f x = f (f x)

请注意,我刚刚开始学习haskell并解释我,因为我是一个假人 .

1 回答

  • 6
    doWork f x = f f x
    

    doWork 有两个参数, fx .

    f f x
    

    我们用两个参数调用 f ,所以 f 必须是一个函数 .

    f :: a -> b -> c
    

    现在, abc 是什么?那么, c 就是整个事物的结果类型 . bx 的类型 . a 是...... f 本身的类型 . 但这意味着 a == a -> b -> c . 如果用 a -> b -> c 替换 a ,你就得到了

    f :: (a -> b -> c) -> b -> c
    

    但它仍然有 a . 如果我们再次替换,我们得到

    f :: ((a -> b -> c) -> b -> c) -> b -> c
    f :: (((a -> b -> c) -> b -> c) -> b -> c) -> b -> c
    

    等等,永远 . 问题是, a == a -> b -> ca 定义为提及自身的类型 - 无限类型循环 . 这是不允许的 .


    另一方面,如果我们有

    f (f x)
    

    那么 f 是一个1参数函数

    f :: a -> b
    

    由于内部 f 的输出作为输入传递给外部 f ,因此两种类型必须相同: a == b

    f :: b -> b
    

    这是一个非常明智的类型 . 所以这里没问题 .

相关问题