gpt4 book ai didi

haskell - 如何在 GHCI 中发现函数的优先级和关联性?

转载 作者:行者123 更新时间:2023-12-04 08:59:38 24 4
gpt4 key购买 nike

是否有一种快速简便的方法来发现 GHCI 中的函数的优先级和关联性?

我发现一种简单的方法是强制将一个运算符与另一个运算符组合,直到出现优先解析错误(PPE)。例如,要发现 !! 的优先级/关联性,我们可以定义infix n的10个不同的运算符对于 0 ≤ n < 10 :

>>> let infix 0 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
>>> let infix 1 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
[...]
>>> let infix 8 %; (%) = ($)
>>> undefined % undefined !! undefined
*** Exception: Prelude.undefined
>>> let infix 9 %; (%) = ($)
>>> undefined % undefined !! undefined

<interactive>:21:1:
Precedence parsing error
cannot mix `%' [infix 9] and `!!' [infixl 9] in the same infix expression

该错误告诉您优先级和固定性是什么。由于定义的 10 个函数是非关联的,因此当优先级相同时,没有机会避免 PPE。天真的方法是尝试每个关联性的 10 个函数,给出 20 的 WCET(因为如果您从与目标相同的关联性开始,具有该关联性的 10 个会通过,但是一旦您到达 kth 下一个关联性的优先级,其中 k 是目标函数的优先级)。

但是有更快的方法吗?我 您可以进行平分以平均达到 log(10) 步。例如,如果目标是 !!!定义为 !! , 但使用 infixl 6 , 我们可以做一个表达式 (:[]) % "AB" !!! 1 , 其中 %是相同的 10 个虚拟函数之一。如果 % 的优先级太低而不会导致 PPE,表达式将产生 "B" (因为表达式将解析为 (:[]) % ("AB" !!! 1) ),而如果优先级太高,则会产生 (因为表达式将解析为 ((:[]) % "AB") !!! 1 )。例子:
>>> let infixl 6 !!!; (!!!) = (!!)
>>> let infix 5 %; (%) = ($)
>>> (:[]) % "AB" !!! 1
"B"
>>> --too low
>>> let infix 7 %; (%) = ($)
>>> (:[]) % "AB" !!! 1
"*** Exception: Prelude.(!!): index too large

>>> --too high
>>> let infix 6 %; (%) = ($)
>>> (:[]) % "AB" !!! 1

<interactive>:10:1:
Precedence parsing error
cannot mix `%' [infix 6] and `!!!' [infixl 6] in the same infix expression
>>> --got it

但是,我不确定这种方法。
  • 您必须保持下一个要猜哪个数字的心理状态,并在脑海中进行除法等(通过纸/计算器可能比直接方法中的 10 个步骤要慢)
  • 是否完全通用?你总能像这样构造一个测试表达式吗?
  • 我不确定我是否总能比直接的方法更快地想出这样的表达式。在这种情况下确实更快,我实际上想出了二分法之前 我想出了简单的方法
  • 如果前面的担忧成立,是否存在一种完全通用的方法来自动生成这种表达式?

  • 有人知道替代方法吗?我可以想象可能有一种方法可以一步完成。但是一个小时后,我能想到的最好的方法就是这种二分法。

    最佳答案

    是的。您可以使用 :info命令。

    Prelude> :info (+)
    class Num a where
    (+) :: a -> a -> a
    ...
    -- Defined in `GHC.Num'
    infixl 6 +

    Prelude> :info (.)
    (.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in `GHC.Base'
    infixr 9 .

    Prelude> :info ($)
    ($) :: (a -> b) -> a -> b -- Defined in `GHC.Base'
    infixr 0 $

    如果不说,则默认为 infixl 9 .

    关于haskell - 如何在 GHCI 中发现函数的优先级和关联性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23586520/

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