How to add type annotation in let binding

前端 未结 3 747
陌清茗
陌清茗 2021-02-01 04:14

I\'m a beginner(ish) in Haskell and I find error message really hard to understand (I guess it comes with time). Anyway, to help me understanding my mistakes, I tried to add int

相关标签:
3条回答
  • 2021-02-01 04:44

    This should work:

    f :: s -> s
    f x =
       let y = undefined :: s
       in  y
    

    Just use the normal :: operator as shown in the above example for type annotation.

    Update:

    It doesn't seem to work with polymorphic types. But it works with an concrete type.

    The following typechecks:

    f :: Int -> Int
    f x = let m = x :: Int
          in m
    

    This produces error:

    f1 :: a -> a
    f1 x = let m = x :: a
           in m
    
    0 讨论(0)
  • 2021-02-01 04:46

    Solution

    You need the ScopedTypeVariables extension for this to work, like this:

    {-# LANGUAGE ScopedTypeVariables #-}
    
    f :: forall a. a -> a
    f x = 
        let x' = x :: a
        in x'
    

    Explanation

    If you have a type signature like this

    f :: a -> a
    

    then it indicates that f is polymorphic and works for any choice of a. So f could be used at type Int -> Int, or at type Bool -> Bool, or at type [Int -> Bool] -> [Int -> Bool] – whatever you like.

    If you have a type annotation like this

    x :: a
    

    it means a similar thing, namely that x should be usable at any type of your choice. But that's not true in your case. The outer function f is polymorphic, but within the function, x has to be of the same type a that the user has chosen for the outer x. By default, Haskell makes no connection between type variables occurring in different type signatures and annotations. However, you can tell it to do so by enabling the ScopedTypeVariables extension. Now, by prefixing a -> a with forall a., you can explicitly instruct Haskell to make a visible as a specific type variable within the definition of f. If you then annotate x :: a, it refers to the outer a rather than a new polymorphic a.

    0 讨论(0)
  • 2021-02-01 04:46

    For anyone who is looking to type annotate the binding instead of the expression - ScopedTypeVariables allows you to do that too!

    f1 = do
      let x :: Int = 5
      y :: Int <- someMonadicOperation
      return $ x + y
    
    0 讨论(0)
提交回复
热议问题