gpt4 book ai didi

元组内的 Haskell 箭头

转载 作者:行者123 更新时间:2023-12-04 11:42:27 25 4
gpt4 key购买 nike

我想创建一个元组,它包含一个箭头和一个描述箭头的字符串。如果我使用函数(而不是箭头)这样做,则以下工作如预期:

funTimes10 = (*10)
describe10 = "times 10"

tuple10 :: (Num b) => ((b -> b), String)
tuple10 = (,) funTimes10 describe10

我可以使用 fst 访问该功能, 和 snd我得到了函数的描述字符串。

但是,如果我用箭头交换函数,如下所示:
aTuple10 :: (Arrow a, Num b) => (a b b, String)
aTuple10 = (,) (arr funTimes10) describe10
  • fst仍然有效并返回我的箭头,但
  • 我没有得到任何带有 snd 的描述字符串.

  • 我只收到此错误消息:
    Ambiguous type variable `a0' in the constraint:
    (Arrow a0) arising from a use of `aTuple10'
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `snd', namely `aTuple10'
    In the expression: (snd aTuple10)
    In an equation for `it': it = (snd aTuple10)

    为什么我会收到这个错误,我应该怎么做才能避免它?

    最佳答案

    我们来看看snd的类型:

    snd :: (foo, x) -> x

    (为了清楚起见,我重命名了类型变量)

    类型说明的是对于类型为 foo 的元组和 x , 返回 x 类型的东西.这里要知道的重要一点是,值(value)体系又名。 Haskell 中的 runtime 是惰性的,Haskell 的类型系统是严格的,这意味着 foox必须在 snd 之前知道可以调用。

    在第一种情况下,当您只有 Num b => (b -> b, String) , 调用 snd将离开 b模棱两可,因为您没有在任何地方提及它的具体类型,并且无法从返回类型中推断出来,因为 foo ~ b这与 x 不同.换句话说:因为 (b, b)可以是任意数字类型的元组,类型检查器无法判断是哪一个,是模棱两可的。这里的技巧是我们将启动 Haskell 的默认规则,该规则规定如果数字类型不明确,则默认为 Integer .如果您使用 -Wall 打开警告,它会说这正在发生。所以,我们的类型变成了 (Integer -> Integer, String)snd可以调用。

    然而,在第二种情况下,我们仍然设法推断出 b通过默认规则,但没有默认 Arrow对于 a ,所以我们被卡住了!您必须明确指定您想要的箭头才能继续!您可以先使用 aTuple10 的值来执行此操作。别的地方:
    let bla = aTuple10  -- We do this because `aTuple10` can have type variables, but `bla` cannot (by default)
    fst bla (23 :: Int) -- This fixes the type of `bla`, so that `a ~ (->)` and `b ~ Int`
    print $ snd bla -- So the arrow isn't ambiguous here

    ...或者您可以只指定您想要的类型:
    print $ snd (aTuple10 :: (Int -> Int, String))

    PS 如果要更改模糊数字的默认类型, default keyword可以帮助你。

    关于元组内的 Haskell 箭头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9465876/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com