什么是FlexibleContexts扩展适合?你能用一个简单的例子解释一下吗?

jhe*_*dus 35 haskell ghc

我试图通过搜索网页来了解FlexibleContexts扩展正在做什么,这些网页可以解释为凡人(例如,像我一样读过LYHFGG的人),但我没有找到任何这样的资源.

因此,我向专家们询问这个话题:有人可以解释一下这个扩展的作用,它为什么存在,并给出一两个简单的例子,说明如何以及为什么要使用它?

此外,如果我读别人的代码,其使用这个扩展名,那我怎么知道,以了解使用此扩展编写的代码扩展?

Die*_*lan 53

如果没有FlexibleContexts函数定义的所有类型类约束,则必须具有类型变量.例如:

add :: Num a => a -> a -> a 
add = (+)
Run Code Online (Sandbox Code Playgroud)

a类型变量在哪里.随着FlexibleContexts启用你可以有任何类型的一个类型类里面.

intAdd :: Num Int => Int -> Int -> Int 
intAdd = (+)
Run Code Online (Sandbox Code Playgroud)

这个例子非常人为,但它是我能想到的最简单的例子.FlexibleContexts通常只用于MultiParamTypeClasses.这是一个例子:

class Shower a b where
  myShow :: a -> b

doSomething :: Shower a String => a -> String
doSomething = myShow
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到我们说我们只想要一个Shower a String.没有FlexibleContexts String必须是类型变量而不是具体类型.

  • 我发现[Free monad](https://hackage.haskell.org/package/free-3.2/docs/Control-Monad-Free.html)的`Show`实例是这个扩展用途的一个很好的例子. (3认同)
  • 感谢您的解释。一个小的称呼`add :: Num a => a-> a`应该是`add :: Num a => a-> a-> a`,因为`(+):: Num a => a-> a ->一个 (2认同)

bhe*_*ilr 7

通常它与MultiParamTypeClasses扩展一起使用,例如在使用mtl您可能编写的库时

doSomethingWithState :: MonadState MyState m => m ()
doSomethingWithState = do
    current <- get
    let something1 = computeSomething1 current
        something2 = computeSomething2 current something1
    put something2
Run Code Online (Sandbox Code Playgroud)

而同样与MonadReaderMonadWriter,以及其他类似的类型类.没有FlexibleContexts你不能使用这个约束.

(请注意,这个答案是基于@ DiegoNolan的,但改写后使用了一个对LYAH读者有意义的现有库).


Dog*_*her 5

除了上面提到的那些以外,我还发现了它的用途:它可以从GHC中获得更清晰的错误消息。例如通常

Prelude> max (1, 2) 3

<interactive>:1:1: error:
    • Non type-variable argument in the constraint: Num (a, b)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a b.
              (Num (a, b), Num b, Num a, Ord b, Ord a) =>
              (a, b)
Run Code Online (Sandbox Code Playgroud)

并启用FlexibleContexts:

Prelude> max (1, 2) 3

<interactive>:1:1: error:
    • No instance for (Num (Integer, Integer))
        arising from a use of ‘it’
    • In the first argument of ‘print’, namely ‘it’
      In a stmt of an interactive GHCi command: print it
Run Code Online (Sandbox Code Playgroud)

这是一个讨论