3

Is there any advantage in haskell to write a local closure like below ?

-- | A fix-point type.
newtype Fix f = Fix { unFix :: f (Fix f) }

-- | Fold 'Fix'.
foldFix :: Functor f => (f a -> a) -> Fix f -> a
foldFix f = go where go = f . fmap go . unFix --- go closes over f

foldFix2 :: Functor f => (f a -> a) -> Fix f -> a
foldFix2 f = f . fmap (foldFix f) . unFix
nicolas
  • 9,549
  • 3
  • 39
  • 83
  • (ps : it might be just for readability, as indeed `foldFix f` is thought of as an honest "go" function going deeper on level. candid question here ..) – nicolas Mar 18 '21 at 18:23
  • I don't think you can say that "go closes over f" because `go` is not a lexical function. – Fyodor Soikin Mar 18 '21 at 18:35
  • 1
    The suggested question about recursion schemes is an almost perfect match, except that its question body doesn't directly mention the `go` trick. To make up for that, I have added two supplementary suggestions. – duplode Mar 18 '21 at 18:36
  • 1
    @FyodorSoikin: Authors differ. In GHC, any term may effectively denote a closure object, whether it’s a syntactic function or not. `go` closes over `f` in the sense that `go` isn’t a *closed term*, so in order to return it from `foldFix`, the compiler must close it over `f` (for example, through closure conversion). The last `->` arrow in the type signature of `foldFix` is implicitly a closure/exponential, rather than a bare function/morphism. In practice, GHC also hides many different isomorphic objects behind the same Haskell types such as `->`. – Jon Purdy Mar 20 '21 at 00:23

0 Answers0