haskell - 哪些类型的问题可以帮助 "higher-kinded polymorphism"更好地解决?

标签 haskell polymorphism higher-kinded-types

当我阅读 History of Haskell 中的一些部分时,我发现:

However, higher-kinded polymorphism has independent utility: it is entirely possible, and occasionally very useful, to declare data types parameterised over higher kinds, such as:

data ListFunctor f a = Nil | Cons a (f a)

了解“基本”ADT,我在这里有点困惑,我的“猜测”是括号中的部分建议“参数”/“动态”一元数据构造函数 f?那么任何类型为 * -> * 的数据构造函数“可以接受”类型 a 吗?我的想法是正确的还是我误解了语法?我知道我“只是猜测”,但我希望在这里获得对此功能的“外行程序员”直觉,一些示例场景需要(或从中受益匪浅);)大多数情况下我可以想象(只是不是在什么情况下)确切的方式)这使得那些“小型嵌入式通用可递归配置语言”-ADT 具有更大的灵 active ,Haskell 非常乐意为这些“小型嵌入式通用可递归配置语言”制定和编写评估......关闭?

在 GHCi 中,上面的 :i ListFunctor 给出:

type role ListFunctor representational nominal
data ListFunctor (f :: * -> *) a = Nil | Cons a (f a)

所以这似乎是从更清晰的 data 声明中“推断”出来的。

最佳答案

是的,f 可以是任何一元类型构造函数。

例如 ListFunctor [] IntListFunctor Maybe Char 都是很好的。

f 也可以是任何 n 元类型构造函数,部分应用了 (n-1) 个参数。

例如,ListFunctor ((->) Bool) IntListFunctor (Either ()) Char 都是很好的。

基本的分类系统非常简单。如果 F::* -> * -> ... -> *,则 F 需要类型参数。如果 G::(* -> *) -> *,则 G 需要任何 * -> * 类型,包括一元类型构造函数以及部分应用如上所示。等等。

<小时/>

高级类型可以很好解决的一个问题是配置选项。假设我们有一条记录

data Opt = Opt 
   { opt1 :: Bool
   , opt2 :: String
   -- many other fields here
   }

现在,配置设置可以在文件中找到和/或通过命令行和/或环境变量传递。在解析所有这些设置源的过程中,我们需要面对这样一个事实:并非所有源都定义所有选项。因此,我们需要更宽松的类型来表示配置设置的子集:

data TempOpt = TempOpt 
   { tempOpt1 :: Maybe Bool
   , tempOpt2 :: Maybe String
   -- many other fields here
   }

-- merge all options in one single configuration, or fail
finalize :: [TempOpt] -> Maybe Opt
...

这太可怕了,因为它重复了所有选项!我们很想删除 Opt 类型,而只使用较弱的 TempOpt,以减少困惑。但是,通过这样做,每次我们需要访问程序中选项的值时,即使在初始配置处理部分之后,我们也需要使用一些部分访问器,例如 fromJust

我们可以采用更高的类型:

data FOpt f = FOpt 
   { opt1 :: f Bool
   , opt2 :: f String
   -- many other fields here
   }
type Opt = FOpt Identity
type TempOpt = FOpt Maybe

-- as before: merge all options in one single configuration, or fail
finalize :: [TempOpt] -> Maybe Opt
...

不再有重复。在我们最终确定配置设置后,我们得到了设置始终存在的静态保证。我们现在可以使用total访问器runIdentity来获取它们,而不是危险的fromJust

关于haskell - 哪些类型的问题可以帮助 "higher-kinded polymorphism"更好地解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42370444/

相关文章:

c++ - 动态选择要在 std::map 中使用的比较仿函数

function - 在没有更高类型 (HKT) 支持的情况下,如何在 Rust 中创建通用结构?

scala - Scala中的更高种类类型

scala - 具有多种类型的类型的仿函数实现

haskell - 在 Haskell 中引用单例列表构造函数的惯用方式是什么?

Haskell 实例模拟?

Haskell 数字列表处理

haskell - 高阶函数和缺乏递归

assembly - 自修改代码算法

c++ - 多态性和动态转换