首页 > 解决方案 > F 尖锐参数化类型 - 笛卡尔积

问题描述

Scott Wlaschin 有一个关于解析器组合器的很棒的教程。

其中有这段代码:

type Result<'a> =
    | Success of 'a
    | Failure of string

type Parser<'a>  = Parser of (string -> Result<'a * string>)

我知道 Result 类型由 'a 参数化,并且使用构造的对象Parser包含一个函数 from stringto Result<'a * string>

我不明白<'a * string>。我知道这是笛卡尔积,Result可以是 aSuccess of 'a或 a Failure of string,但类型Result不是。Result<'a>Result<'a * string>

显然我错过了一些东西,我会很感激一些帮助!

提前致谢

标签: typesf#

解决方案


那些不一样'a。在 的定义中有一个'a,在 的定义中有Result一个完全不同的、不相关'aParser

为了进一步解释,我将重命名其中一个,否则它只是口头上的意大利面条:

type Result<'a> =
    | Success of 'a
    | Failure of string

type Parser<'b>  = Parser of (string -> Result<'b * string>)

所以在这里,在 的定义中Parser,我们使用Result,并将其'b * string作为参数。因此,在 的定义中Result'a = 'b * string

这反过来意味着有两个可能的值:

  1. Success of ('b * string)
  2. Failure of string

这意味着解析器可能会失败(将错误作为 a 返回string)或成功,在这种情况下,它会返回结果解析值'b加上输入文本的“剩余部分”(也称为“未使用的部分”)。


从您的评论看来,您可能会因为'a * string似乎反映Result案例Success of 'aFailure of string.

这种看似对称的​​现象纯属巧合。Parser类型只需要与类型本身的结构'a * string完全无关的原因。Result

为了进一步说明,这里有一些其他同样有效的类型:

type T = Result<int>
type U = Result<bool list>
type V<'a> = Result<int * 'a * string>
type W = Result<Result<float>>
type F<'q> = 'q -> Result<obj>
type G = Result<string> -> int
type H<'a, 'b, 'c> = Result<'a> -> Result<'b> -> Result<'c>

推荐阅读