How to relate to type from outer context

后端 未结 2 1514
太阳男子
太阳男子 2020-12-29 02:21

Let us consider the following code snippet:

blah :: a -> b -> a
blah x y = ble x where
    ble :: b -> b
    ble x = x

This compil

相关标签:
2条回答
  • 2020-12-29 03:04

    If you don't want to use ScopedTypeVariables, you can use the good ole fashion asTypeOf function.

    -- defined in Prelude
    asTypeOf :: a -> a -> a
    x `asTypeOf` y = x
    

    blah :: a -> b -> a
    blah x y = ble x where
        ble x = x `asTypeOf` y
    

    Of course, this won't compile because of the type error.

    Update:

    I would like to point out that sometimes you might have to be a little crafty to do what you want with asTypeOf. Take the following example that superflously uses asTypeOf because I don't want to think of a case that actually needs asTypeOf. Similar solutions would work the same for real world cases.

    foo :: Bounded a => Maybe a -> a
    foo m = x
      where
        x = maxBound -- Q: how do I make (x :: a) when given (Maybe a)?
        _ = Just x `asTypeof` m -- A: witchcraft!
    
    0 讨论(0)
  • 2020-12-29 03:12

    This is possible with the ScopedTypeVariables extension. You need to use explicit forall's to bring the type variables into scope.

    blah :: forall a b. a -> b -> a
    blah x y = ble x where
        ble :: b -> b
        ble x = x
    

    Trying to load this definition with ScopedTypeVariables enabled gives:

    foo.hs:2:16:
        Couldn't match type `a' with `b'
          `a' is a rigid type variable bound by
              the type signature for blah :: a -> b -> a at foo.hs:2:1
          `b' is a rigid type variable bound by
              the type signature for blah :: a -> b -> a at foo.hs:2:1
        In the first argument of `ble', namely `x'
        In the expression: ble x
        In an equation for `blah':
            blah x y
              = ble x
              where
                  ble :: b -> b
                  ble x = x
    

    You can tell that GHC interprets the two bs as the same type because the error says that a and b are bound on the same line.

    0 讨论(0)
提交回复
热议问题