Lack of type inference results in failed compilation, lack of instance ambiguity

I am focused on why this code compiles with type hints, but does not compile without it. There should not be any ambiguity of instances (there is one instance).

class Monad m => FcnDef β m | β -> m where
    def :: String -> β -- takes a name

instance Monad m => FcnDef (m α -> m α) m where
    def s body = body

dummyTest :: forall m. Monad m => m ()
dummyTest = def "dummy" ((return ()) :: m ())

On the other hand, if you omit declarations :: m ()or all types, compilation will fail,

No instance for (FcnDef (m0 () -> t0) m0)
  arising from a use of `def'

To clarify, the code tries to create a multivariate type for def, so you can write, for example,

def "dummy2" "input" $ \in -> return ()

Edit

This question is more interesting than the problem of restricting monomorphism. If you add such code, then it resolves instances to specific types, namely

dummyTest = def "dummy" (return ())
g :: IO ()
g = dummyTest

compilation does not work the same way.

+5
2

.

- .

dummyTest = ...

, . .

, , . - . ? . !

.

dummyTest :: forall m. Monad m => m ()
dummyTest = def "dummy" (return ())

def FcnDef β m => String -> β, def . , β . x -> y.

, y m (), . , return () Monad m1 => m1 (), , def, , FcnDef (m1 () -> m ()) m0 => def :: String -> m1 () -> m ().

. , m1 m. :

Could not deduce (FcnDef (m1 () -> m ()) m0)
  arising from a use of `def'
from the context (Monad m)
  bound by the type signature for dummyTest :: Monad m => m ()
  at FcnDef.hs:10:1-51
Possible fix:
  add (FcnDef (m1 () -> m ()) m0) to the context of
    the type signature for dummyTest :: Monad m => m ()
  or add an instance declaration for (FcnDef (m1 () -> m ()) m0)
In the expression: def "dummy" ((return ()))
In an equation for `dummyTest':
    dummyTest = def "dummy" ((return ()))

, , - , , .

, , , .

class Monad m => FcnDef β m | β -> m where
    def :: String -> β -> β

instance Monad m => FcnDef (m α) m where
    def s body = body

-- dummyTest :: forall m. Monad m => m ()
dummyTest = def "dummy" (return ())

, return , , NoMonomorphismRestriction, .

, 100%, , , , .

+7

@pigworker :

. , var . , - .

, @hammar , , , , . , :

instance Monad m => FcnDef (m α -> m α) m where -- etc...
instance Monad m => FcnDef (m1 α -> m2 b) m3 where -- etc...

? , . , , , ; OverlappingInstances .

, - , , , , , GHC. , , - ( !), . TypeFamilies, ~ :

instance (m1 ~ m2, m2 ~ m3, a ~ b, Monad m) => FcnDef (m1 α -> m2 b) m3 where -- etc...

, , GHC , . , , , . , . , , , , , .

, , .

+3

All Articles