我的操作数据如下所示:
type IHasShow =
abstract member show:bool
type ShowHideNotCompletedData = {show:bool}
type ShowHideCompletedData = {show:bool}
[<Pojo>]
type ActionData =
| ShowHideNotCompleted of ShowHideNotCompletedData
| ShowHideCompleted of ShowHideCompletedData
后来我尝试将 ShowHideNotCompletedData 或 ShowHideCompletedData 传递给函数,该函数只关心 bool “show”成员,但无法弄清楚如何传递/转换它:
let setShowItem (data:IHasShow) negate item =
if data.show && (negate item.completed) then
{ item with show = true}
else if (negate item.completed) then
{ item with show = false}
else
item
但是如何调用这个函数呢?
let setShowFn = setShowItem (data :> IHasShow) not
错误:
Type constraint mismatch. The type
'ShowHideNotCompletedData'
is not compatible with type
'IHasShow'
尝试过
let setShowFn = setShowItem data not
错误:
The type 'ShowHideNotCompletedData' is not compatible with the type 'IHasShow'
除了复制粘贴 setShowItem 并采用 ShowHideNotCompletedData 和 ShowHideCompleted 之外,还有其他方法吗?
如果有帮助;完整的源代码在这里:https://github.com/amsterdamharu/riot_redux_fable
最简单的解决方案是不传递数据,而只传递 bool 值:
let setShowItem show negate item =
if (negate item.completed) then//simplified if statement
{ item with show = show}
else
item
//...
| ShowHideCompleted data ->
let setShowFn = setShowItem data.show id
{ state with
showCompleted = data.show
items = state.items
|> Array.map setShowFn}
我仍然想知道如何定义泛型类型并传递它。
最佳答案
在您当前的解决方案中,您的两种类型 ShowHideNotCompletedData
和 ShowHideCompletedData
是记录。它们具有接口(interface)的所有字段,但没有显式实现它们。解决方案是使接口(interface)显式化:
type ShowHideNotCompletedData(show) =
interface IHasShow with
member this.show = show
type ShowHideCompletedData(show) =
interface IHasShow with
member this.show = show
实例化为ShowHideNotCompletedData true
。对于替代解决方案,您可能需要咨询一些有关鸭子类型的 SO 问题,例如 this
话虽如此:我有一种预感,您的数据类型定义有点太复杂了。 @robkuz 发布了一个没有界面的答案。您自己的建议是将 bool 传递到函数中,这在模块化和可测试性方面似乎更好。
关于F# 如何将接口(interface)传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42275890/