最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

list - Solving Ambiguous type variable errors without adding a specific type annotation - Stack Overflow

programmeradmin3浏览0评论

I would like to make this code compile and run:

import Data.List
main = print $ elemIndices [] []

Without adding specific type annotations. The error it gives is:

Ambiguous type variable ‘a0’ arising from a use of ‘elemIndices’
      prevents the constraint ‘(Eq a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Eq Ordering -- Defined in ‘GHC.Classes’
        instance Eq Integer
        ...plus 21 others

I believe problems are specific to functions like elemIndices, sortOn, etc, since it needs to be solved since it uses Eq (or Ord/etc)

The reason I would not like to add specific type annotations is because I am actually compiling another language to Haskell and I need empty lists to remain flexible on their behavior (in case the same value is used elsewhere).

For example, if you had this code and gave a a specific type then it would no longer work:

main=do
   print $ zipWith (+) a [1,2]
   print $ zipWith (zipWith (+)) a [[1],[2]]
   where
      a = []

I am hoping there is a simple solution to this, but all recommendations I have seen have just said to use type annotations. I think there might be a simple solution since the code in question works in ghci but not compiled haskell code.

These examples may seem stupid, but it is important for them to work because my language does some things dynamically based on input, no input would have a value of [] (with no type). So even if you do take input it needs to not compiler error for cases like this that would never run (and it couldn't know in advance would never run).

I would like to make this code compile and run:

import Data.List
main = print $ elemIndices [] []

Without adding specific type annotations. The error it gives is:

Ambiguous type variable ‘a0’ arising from a use of ‘elemIndices’
      prevents the constraint ‘(Eq a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance Eq Ordering -- Defined in ‘GHC.Classes’
        instance Eq Integer
        ...plus 21 others

I believe problems are specific to functions like elemIndices, sortOn, etc, since it needs to be solved since it uses Eq (or Ord/etc)

The reason I would not like to add specific type annotations is because I am actually compiling another language to Haskell and I need empty lists to remain flexible on their behavior (in case the same value is used elsewhere).

For example, if you had this code and gave a a specific type then it would no longer work:

main=do
   print $ zipWith (+) a [1,2]
   print $ zipWith (zipWith (+)) a [[1],[2]]
   where
      a = []

I am hoping there is a simple solution to this, but all recommendations I have seen have just said to use type annotations. I think there might be a simple solution since the code in question works in ghci but not compiled haskell code.

These examples may seem stupid, but it is important for them to work because my language does some things dynamically based on input, no input would have a value of [] (with no type). So even if you do take input it needs to not compiler error for cases like this that would never run (and it couldn't know in advance would never run).

Share Improve this question asked Mar 18 at 1:08 Darren SmithDarren Smith 2251 silver badge6 bronze badges 3
  • I'm not sure if it helps, but you might want to give ExtendedDefaultRules extension (downloads.haskell./ghc/latest/docs/users_guide/…) a look. – snak Commented Mar 18 at 1:28
  • Your example is silly: a can be (and is) given the type forall a. [a]. What are you actually trying to do? – Naïm Favier Commented Mar 18 at 1:39
  • @NaïmFavier there are two examples, that does not work for the first one. I believe the question already addresses other notes. – Darren Smith Commented Mar 18 at 20:33
Add a comment  | 

3 Answers 3

Reset to default 2

For example, if you had this code and gave a a specific type then it would no longer work:

main=do
   print $ zipWith (+) a [1,2]
   print $ zipWith (zipWith (+)) a [[1],[2]]
   where
      a = []

You can give a a type in two different places:

  1. At the definition site:

    main=do
       print $ zipWith (+) a [1,2]
       print $ zipWith (zipWith (+)) a [[1],[2]]
       where
         a :: [Int] 
         a = []
    

    This does indeed break the code.

  2. At the use sites:

    main=do
       print $ zipWith (+) (a :: [Int]) [1,2]
       print $ zipWith (zipWith (+)) (a :: [[Int]]) [[1],[2]]
       where
         a = []
    

    This does not break the code.

So if you want to reuse the same variable or function in many places, but still disambiguate its type, then you should specify the specific type at the use sites.

Using {-# LANGUAGE ExtendedDefaultRules #-} solves the problem and the first example works with it. Thank you @snak for the tip!!

If you need your empty lists to stay flexible, then annotate something else.

import Data.List
main = print $ (elemIndices :: [Bool] -> [[Bool]] -> [Int]) [] []

This can be made more compact with type applications.

{-# Language TypeApplications #-}
import Data.List
main = print $ elemIndices @[Bool] [] []
发布评论

评论列表(0)

  1. 暂无评论