[GHC] #14426: Inferred type not principle/most general?

#14426: Inferred type not principle/most general? -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The type inferred for `(#)` is `H a a -> H a a -> H a a` (from [https://arxiv.org/pdf/1309.5135.pdf Coroutining Folds with Hyperfunctions]) {{{#!hs newtype H a b = Fn { invoke :: H b a -> b } -- ( # ) :: H a a -> H a a -> H a a f # g = Fn (\k -> invoke f (g # k)) }}} but a more general type is actually {{{#!hs ( # ) :: H b c -> H a b -> H a c f # g = Fn (\k -> invoke f (g # k)) }}} Is this expected or a blind spot in type inference ---- Same thing in ''ghci'' {{{ $ ghci -ignore-dot-ghci GHCi, version 8.3.20170920: http://www.haskell.org/ghc/ :? for help Prelude> :set prompt "> "
newtype H a b = Fn { invoke :: H b a -> b }
f # g = Fn (\k -> invoke f (g # k)) :t ( # )
( # ) :: H a a -> H a a -> H a a
let ( # ) :: H b c -> H a b -> H a c; f # g = Fn (\k -> invoke f (g #
k))
:t ( # ) ( # ) :: H b c -> H a b -> H a c }}}
Interestingly writing it in terms of `fix` does not type check with the more general type {{{
import Data.Function :t fix $ \self -> \f g -> Fn (\k -> invoke f (self g k)) fix $ \self -> \f g -> Fn (\k -> invoke f (self g k)) :: H a a -> H a a -> H a a :t (fix $ \self -> \f g -> Fn (\k -> invoke f (self g k))) :: H b c -> H a b -> H a c
<interactive>:1:2: error: • Couldn't match type ‘b1’ with ‘a1’ ‘b1’ is a rigid type variable bound by an expression type signature: forall b1 c1 a1. H b1 c1 -> H a1 b1 -> H a1 c1 at <interactive>:1:60-82 ‘a1’ is a rigid type variable bound by an expression type signature: forall b1 c1 a1. H b1 c1 -> H a1 b1 -> H a1 c1 at <interactive>:1:60-82 Expected type: H b1 c1 -> H a1 b1 -> H a1 c1 Actual type: H a1 a1 -> H a1 a1 -> H a1 a1 • In the expression: (fix $ \ self -> \ f g -> Fn (\ k -> ...)) :: H b c -> H a b -> H a c }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14426 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14426: Inferred type not principle/most general? -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * status: new => closed * resolution: => invalid Comment: This is expected behavior. The issue is that the `Fn` constructor uses polymorphic recursion, and type inference in the presence of polymorphic recursion is known to be undecidable. You managed to get lucky and have GHC infer any type at all for `(#)`, but often type inference will fail completely in the presence of polymorphic recursion, as in the example below: {{{#!hs data FullTree a = Leaf | Bin a (FullTree (a, a)) -- size :: FullTree a -> Int size Leaf = 0 size (Bin _ t) = 1 + 2 * size t }}} See the [https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-810004.... Haskell Report's section on type signatures] for more. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14426#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14426: Inferred type not principle/most general? -------------------------------------+------------------------------------- Reporter: Iceland_jack | Owner: (none) Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Iceland_jack): Ah polymorphic recursion, that's right. Thanks Ryan -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14426#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC