<div dir="ltr"><br><br>On Saturday, March 15, 2014 10:21:36 AM UTC-4, Silvio Frischknecht wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi<p>I have been playing around a bit with closed type families. However, I somehow <br>always bump my head at the fact that things usually doesn't work for Num <br>without specifying the type.</p><p>Here is an example.</p><p>    {-# LANGUAGE FlexibleInstances         #-}<br>    {-# LANGUAGE FlexibleContexts          #-}<br>    {-# LANGUAGE TypeFamilies              #-}<br>    {-# LANGUAGE DataKinds                 #-}<br>    {-# LANGUAGE UndecidableInstances      #-}<br>    {-# LANGUAGE OverlappingInstances      #-}<br>    {-# LANGUAGE IncoherentInstances       #-}<br>    module Main where</p><p>    import Data.Typeable</p><p>    type family UnMaybed a where<br>        UnMaybed (Maybe a) = a<br>        UnMaybed a = a</p><p>    class UnMaybe x where<br>        unMaybe :: x -> UnMaybed x</p><p>    instance UnMaybe (Maybe a) where<br>        unMaybe (Just a) = a</p><p>    instance (UnMaybed a ~ a) => UnMaybe a where<br>        unMaybe a = a</p><p>    main = do<br>        print $ unMaybe 'c'<br>        print $ unMaybe (1::Int)<br>        print $ unMaybe (Just 1)<br>        print $ unMaybe 1 -- this line does not compile</p><p>everything except the last line will compile.</p><p>    ../Example.hs:23:17:<br>        Occurs check: cannot construct the infinite type: s0 ~ UnMaybed s0<br>        The type variable ‘s0’ is ambiguous<br>        In the second argument of ‘($)’, namely ‘unMaybe 1’<br>        In a stmt of a 'do' block: print $ unMaybe 1</p><p>Now I know this is because numbers are polymorphic and (Maybe a) could be an <br>instance of Num. I think for normal overlapping typeclasses this dilemma can <br>be solved by using the IncoherentInstances PRAGMA. Anyway, I wanted to ask if <br>there is a way to make this work in type families?</p><p>I also thought about specifying Num explicitly in UnMaybed</p><p>    type family UnMaybed a where<br>        unMaybed (Num a => a) = a<br>        UnMaybed (Maybe a) = a<br>        UnMaybed a = a</p><p>This compiles but i think the first case will never be matched this is probably <br>a bug.</p><p>Silvio</p><p>______________________________<wbr>_________________<br>Haskell-Cafe mailing list<br><a href="javascript:" target="_blank" gdf-obfuscated-mailto="OkMqKfXTfGYJ" onmousedown="this.href='javascript:';return true;" onclick="this.href='javascript:';return true;">Haskel...@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fwww.haskell.org%2Fmailman%2Flistinfo%2Fhaskell-cafe\46sa\75D\46sntz\0751\46usg\75AFQjCNHiVycCM53czUVzPma4Fkb_wPqP2A';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fwww.haskell.org%2Fmailman%2Flistinfo%2Fhaskell-cafe\46sa\75D\46sntz\0751\46usg\75AFQjCNHiVycCM53czUVzPma4Fkb_wPqP2A';return true;">http://www.haskell.org/<wbr>mailman/listinfo/haskell-cafe</a><br></p></blockquote><div><br>I'm glad Richard Eisenberg responded here; I was going to point you to https://ghc.haskell.org/trac/ghc/wiki/NewAxioms with the caveat that I don't totally understand the details there.<br><br>A couple things about your example: you actually don't need IncoherentInstances here; OverlappingInstances is sufficient, since the instance head  `UnMaybe (Maybe a)` is more precise than `UnMaybe a`. Personally I'm *much* more comfortable with just OverlappingInstances than IncoherentInstances.<br><br>The other thing to consider is that the only reason why e.g. `print 1` even compiles is because of defaulting rules, which are something of a hack. Maybe that makes you feel better about living with the limitation in your current code.<br><br>Brandon<br></div></div>