作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有可能为记录创建 fmap,以便我可以应用相同的功能来记录类似 bur 不同类型的字段
假设我有一个记录字段类型 Item
和记录X
和功能 transform
type Item<'a, 'b> = Item of 'a * 'b
let transform (i: Item<'a, 'b>) : Item<'a, string> =
let (Item (x, y)) = i
Item (x, sprintf "%A" y)
type X<'a> = {
y: Item<'a, int>
z: Item<'a, bool>
}
with
member inline this.fmap(f) =
{
y = f this.y
z = f this.z
}
z = f this.z
行提示给定类型应该是
Item<'a, int>
但它的类型为
Item<'a, bool>
.显然作为类型推断器
f
是
Item<'a, int> -> Item<...>
类型但是我想要
f
应用多态。我怎样才能完成这项工作?
最佳答案
一个明显的解决方案是使用 bimap
而不是 fmap
然后在调用者站点编写两次函数:
type Item<'a, 'b> = Item of 'a * 'b
let transform (i: Item<'a, 'b>) : Item<'a, string> =
let (Item (x, y)) = i
Item (x, sprintf "%A" y)
type X<'a> = {
y: Item<'a, int>
z: Item<'a, bool>
}
with
member inline this.bimap(f, g) =
{
y = f this.y
z = g this.z
}
Invoke
的方法将某种函数包装在一个类型中。 .类似于委托(delegate)但静态的东西。
$
而不是
Invoke
为简单起见:
let inline fmap invokable ({y = y1; z = z1}) = {y = invokable $ y1; z = invokable $ z1}
type Id = Id with
static member ($) (Id, Item (a,b)) = Item (id a, id b)
type Default = Default with
static member ($) (Default, Item (a:'t,b:'u)) =
Item (Unchecked.defaultof<'t>, Unchecked.defaultof<'u>)
let a = {y = Item ('1', 2); z = Item ('3', true) }
let b = fmap Id a
let c = fmap Default a
type X<'a, 'b, 'c> = {
y: Item<'a, 'b>
z: Item<'a, 'c>
}
type ToList = ToList with static member ($) (ToList, Item (a,b)) = Item ([a], [b])
let d = fmap ToList a
// val d : X<char list,int list,bool list> = {y = Item (['1'],[2]);
z = Item (['3'],[true]);}
关于interface - 如何使用 F# 在记录结构上定义 fmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41123405/
我是一名优秀的程序员,十分优秀!