我可以让这个模棱两可的函数编译吗?

问题描述 投票:0回答:1

首先:我知道我不能使用这个函数,除非我有 TypeApplications 启用。但我想 AllowAmbiguousTypes 是为了解决这个问题。

我目前有以下代码。

{-# LANGUAGE ExplicitForAll, AllowAmbiguousTypes #-}

module A where

class B c where
    d :: forall e. e -> c e

class F g where
    h :: forall i. g i -> i

data J k = J {l :: k}

instance B J where
    d = J

instance F J where
    h = l

m :: forall n o. (B n, F n) => o -> o
m = h . d

用GHCi 8.10.1来解释这个代码 或者用GHC 8.10.1来编译,都会导致这个错误。

j.hs:20:5: error:
    • Could not deduce (F g0) arising from a use of ‘h’
      from the context: (B n, F n)
        bound by the type signature for:
                   m :: forall (n :: * -> *) o. (B n, F n) => o -> o
        at j.hs:19:1-37
      The type variable ‘g0’ is ambiguous
      These potential instance exist:
        instance F J -- Defined at j.hs:16:10
    • In the first argument of ‘(.)’, namely ‘h’
      In the expression: h . d
      In an equation for ‘m’: m = h . d
   |
20 | m = h . d
   |     ^

j.hs:20:9: error:
    • Could not deduce (B g0) arising from a use of ‘d’
      from the context: (B n, F n)
        bound by the type signature for:
                   m :: forall (n :: * -> *) o. (B n, F n) => o -> o
        at j.hs:19:1-37
      The type variable ‘g0’ is ambiguous
      These potential instance exist:
        instance B J -- Defined at j.hs:13:10
    • In the second argument of ‘(.)’, namely ‘d’
      In the expression: h . d
      In an equation for ‘m’: m = h . d
   |
20 | m = h . d
   |         ^

我知道,也许编译器不能在GHCi 8.10.1和GHC 8.10.1之间建立连接 BF 的实例和用途。dh. 我想这样的东西可以解决这个问题。

m @p = h @p . d @p

但是,即使使用 TypeApplications这被拒绝了。

是否有一些语言选项可以让我选择,要么使类似的变通成为可能,要么直接让编译器推断出连接?

haskell types ambiguous
1个回答
7
投票

你的想法是对的,但是没有现成的方法来绑定一个等式左边的类型参数。(有一项工作正在进行中,以将其作为扩展添加,但它遇到了一些边缘情况,需要解决。) 但由于它是一个带有附加类型签名的顶层定义,你可以直接使用那里的类型。

{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}

m :: forall n o. (B n, F n) => o -> o
m = h @n . d @n

使用 ScopedTypeVariables 延长 指类型 n 类型签名中指定的。


5
投票

为了补充实际的答案,您的尝试 (m @p = h @p . d @p)没有编译,因为它使用的符号实际上具有完全不相关的含义。

m @p = ... 并没有定义一个多态函数。m 带类型参数的 p;没有这样的语法(使用 ScopedTypeVariables 是最接近的近似值)。) m@p 是一个如模式,绑定两个变量 mp 到相同的值。@ 当它的右分量是一个非平凡模式时,更常用。

t@(x, y) = somepair

-- equivalent to --

t = somepair
(x, y) = t
© www.soinside.com 2019 - 2024. All rights reserved.