f# - 单一案例歧视工会的目的

标签 f# monads discriminated-union

我正在定义一个单子(monad)可观察/响应式(Reactive)解析器。这与普通解析器的行为完全不同,因为它是连续查询。底层类型是:

IObservable<'a> -> IObservable<'b>

从函数式语言中的各种解析器实现来看,定义事物的更合适方法似乎是单例区分联合:

type Pattern<'a,'b> = Pattern of (IObservable<'a> -> IObservable<'b>)

这意味着我需要提取底层函数才能使用它:

let find (Pattern p) = p

问题是:这只是按照惯例,还是为了以后扩展的目的,或者即使定义从未改变,是否有理由这样做?

额外问题:如果只是为了更方便的类型签名,为什么不直接使用类型别名:

type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b>

我已经在这方面取得了很大进展,并且还没有发现不使用 DU 会影响可组合性的情况。

最佳答案

F# 编译器不会保留有关类型缩写的信息,因此您根本无法从类型推断中受益。类型签名可以理解为程序规范;让类型检查器完成其工作是确保程序正确性的好方法。

在类型别名的情况下,您需要在各处显式指定类型注释:

type Vector = float * float

// val add : float * float -> float * float -> Vector
let add ((x1, y1): Vector) ((x2, y2): Vector): Vector = (x1 + y1, x2 + y2)

但它不会为您提供使用 DU 时的透明度:

type Vector = V of float * float

// val add : Vector -> Vector -> Vector
let add (V(x1, y1)) (V(x2, y2)) = V(x1 + y1, x2 + y2)

在复杂的程序中,清晰的类型签名确实可以更轻松地维护可组合性。

不仅可以更简单地向单例 DU 添加更多案例,而且可以更轻松地使用成员和静态方法扩展 DU。一个例子是您经常重写 ToString() 以实现 pretty-print 。

关于f# - 单一案例歧视工会的目的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10150767/

相关文章:

asp.net - 在非常基本的 WebSharper 应用程序中找不到 '/Scripts/IntelliFactory.WebSharper.dll.js'

performance - 为什么F#中的printf这么慢?

haskell - 理解 Writer Monad 的示例

c++ - 重新定义类成员数据类型

f# - 是否可以对受歧视联合的基础形状进行模式匹配?

wpf - F#/WPF 事件绑定(bind)

haskell - Hoopl 中重写函数内的单子(monad)效应示例?

haskell - 为什么具有 `join` 的函数组合可以更改函数输入?

arrays - 在 F# 数组函数中使用可区分联合时如何定义零元素

F# BinarySearch 返回位置