Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8300009
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T16:23:16+00:00 2026-06-08T16:23:16+00:00

I started doing 99 haskell problems and I was on problem 7 and my

  • 0

I started doing 99 haskell problems and I was on problem 7 and my unittests were blowing up.

Apparently, it’s due to this: http://www.haskell.org/haskellwiki/Monomorphism_restriction

I just wanted to make sure I understood this correctly because I’m kinda confused.

situation 1: func a is defined with no type def or with a non-strict type def and then used once, the compiler has no issues infering the type at compile time.

situation 2: the same func a is used many times in the program, the compiler can’t be 100% sure what the type is unless it recomputes the function for the given arguments.

To avoid the computation loss, ghc complains to the programmer that it needs a strict type def on a
to work correctly.

I think in my situation, assertEqual has the type def of

 assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion

I was getting an error when test3 was defined that I interpreted as saying that it had 2 possible types for the return of testcase3 (Show and Eq) and didn’t know how to continue.

Does that sound correct or am I completely off?

problem7.hs:

-- # Problem 7
-- Flatten a nested list structure.

import Test.HUnit

-- Solution

data NestedList a = Elem a | List [NestedList a]

flatten :: NestedList a -> [a]
flatten (Elem x) = [x]
flatten (List x) = concatMap flatten x

-- Tests

testcase1 = flatten (Elem 5)
assertion1 = [5]

testcase2 = flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]])
assertion2 = [1,2,3,4,5]

-- This explodes
-- testcase3 = flatten (List [])

-- so does this:
-- testcase3' = flatten (List []) :: Eq a => [a]

-- this does not
testcase3'' = flatten (List []) :: Num a => [a]

-- type def based off `:t assertEqual`
assertEmptyList :: (Eq a, Show a) => String -> [a] -> Assertion
assertEmptyList str xs = assertEqual str xs []

test1 = TestCase $ assertEqual "" testcase1 assertion1
test2 = TestCase $ assertEqual "" testcase2 assertion2
test3 = TestCase $ assertEmptyList "" testcase3''

tests = TestList [test1, test2, test3]

-- Main
main = runTestTT tests

1st situation: testcase3 = flatten (List [])

GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( problem7.hs, interpreted )

problem7.hs:29:20:
    Ambiguous type variable `a0' in the constraints:
      (Eq a0)
        arising from a use of `assertEmptyList' at problem7.hs:29:20-34
      (Show a0)
        arising from a use of `assertEmptyList' at problem7.hs:29:20-34
    Probable fix: add a type signature that fixes these type variable(s)
    In the second argument of `($)', namely
      `assertEmptyList "" testcase3'
    In the expression: TestCase $ assertEmptyList "" testcase3
    In an equation for `test3':
        test3 = TestCase $ assertEmptyList "" testcase3
Failed, modules loaded: none.
Prelude> 

2nd situation: testcase3 = flatten (List []) :: Eq a => [a]

GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( problem7.hs, interpreted )

problem7.hs:22:13:
    Ambiguous type variable `a0' in the constraints:
      (Eq a0)
        arising from an expression type signature at problem7.hs:22:13-44
      (Show a0)
        arising from a use of `assertEmptyList' at problem7.hs:29:20-34
    Possible cause: the monomorphism restriction applied to the following:
      testcase3 :: [a0] (bound at problem7.hs:22:1)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction
    In the expression: flatten (List []) :: Eq a => [a]
    In an equation for `testcase3':
        testcase3 = flatten (List []) :: Eq a => [a]
Failed, modules loaded: none.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T16:23:18+00:00Added an answer on June 8, 2026 at 4:23 pm

    It’s not so much the monomorphism restriction, it’s the resolution of ambiguous type variables by defaulting that causes the compilation failure.

    -- This explodes
    -- testcase3 = flatten (List [])
    
    -- so does this:
    -- testcase3' = flatten (List []) :: Eq a => [a]
    
    -- this does not
    testcase3'' = flatten (List []) :: Num a => [a]
    
    flatten :: NestedList a -> [a]
    flatten (Elem x) = [x]
    flatten (List x) = concatMap flatten x
    

    flatten imposes no constraints on the type variable a, so there’s no problem with the definition of testcase3 as such, it would be polymorphic.

    But when you use it in test3,

    test3 = TestCase $ assertEmptyList "" testcase3 -- ''
    

    you inherit the constraints of

    assertEmptyList :: (Eq a, Show a) => String -> [a] -> Assertion
    

    Now the compiler has to find out at which type testcase3 should be used there. There is not enough context to determine the type, so the compiler tries to resolve the type variable by defaulting. According to the defaulting rules, a context (Eq a, Show a) cannot be resolved by defaulting, since only contexts involving at least one numeric class are eligible for defaulting. So compilation fails due to an ambiguous type variable.

    testcase3' and testcase3'' however fall under the monomorphism restriction due to the expression type signature which imposes constraints on the right hand side of the definition that are inherited by the left.

    testcase3' fails to compile due to that, regardless of whether it is used in an assertion.

    testcase3'' gets defaulted to [Integer] since the expression type signature imposes a numeric constraint. Thus when the type is monomorphised for testcase'', the constrained type variable is defaulted to Integer. Then there is no question of the type at which it is used in test3.

    If you had given type signatures to the bindings instead of to the right hand side,

    testcase3' :: Eq a => [a]
    testcase3' = flatten (List [])
    
    testcase3'' :: Num a => [a]
    testcase3'' = flatten (List [])
    

    both values would have compiled on their own to polymorphic values, but still only testcase3'' would be usable in test3, since only that introduces the required numeric constraint to allow defaulting.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Doing the getting started of Sinatra. I get this error: ./sinatra.rb:5: undefined method `get'
I am very new to this site and to programming. I started doing some
Sorry about the confusing title. I recently started doing this in my project, and
I started doing Project Euler and got to problem number 9 . Since I
I've just started doing some PowerShell scripting, and I'm running into a problem testing
So I've got all of this really neato PHP code and I've started doing
It's only started doing this today, so I assumed it was something I've done,
This may be a bit silly question, but I just started doing pretty things
I started doing a new project in PHP / MySql . The Aim of
I just started doing OOP, so I apologize in advance if there is a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.