Haskell中的类型"修复"和函数"修复"如何相同?



我试图说服自己类型Fix和函数fix是一回事.
但我找不到它们的定义之间的相关性

-- definition of fix 
fix :: (p -> p) -> p
fix f = let {x = f x} in x -- or fix f = f (fix f)
-- definition of Fix
newtype Fix f = Fix { unFix :: f (Fix f) }

构造函数Fix如何适应(x -> x) -> x的形式?

查看类型构造函数的类型Fix

> :k Fix
Fix :: (* -> *) -> *

类型构造函数Fix类似于函数fix

数据构造函数是另一回事。按照理解 F 代数中的解释,Fix是一个计算器:它评估类型f (Fix f)的项以生成类型Fix f的值。此评估是无损的;您可以使用unFix从结果中恢复原始值。

让我们以fix的天真实现为例:

fix f = f (fix f)

对于函数f,这将创建如下所示的内容:

f (f (f (f (f (f (f ...

Fixnewtype 执行相同的操作,但适用于类型。因此,如果我们采用类型Maybe,我们将要创建:

Maybe (Maybe (Maybe (Maybe (Maybe (Maybe ...

我们将如何创建一个构造该类型的函数?我们可以先尝试使用类型同义词:

--   fix f = f (fix f)
type Fix f = f (Fix f)

您应该能够看到这与上面fix的天真实现相同,只是进行了一些小的更改。但这不是合法的哈斯克尔!

这是出于多种原因:主要是,Haskell不允许像上面Maybe示例那样的无限类型,并且Haskell的类型系统是严格的,与fix中要求的惰性求值相反。这就是为什么我们需要一个newtype.新的类型定义(随newtypedata引入(允许递归,因此我们采用类型同义词并将其更改为newtype。

type    Fix f =                f (Fix f)
newtype Fix f =                f (Fix f)   -- change to newtype
newtype Fix f = Fix           (f (Fix f))  -- need to have a constructor
newtype Fix f = Fix { unFix :: f (Fix f) } -- And name the field, also

最新更新