作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下代码在“评估”中失败:
“预计此表达式将具有类型的复杂,但这里有双重列表”
我是否在“(+)”上违反了运算符(operator)的重载规则?
如果我更改'(+)'为“添加”。
open Microsoft.FSharp.Math
/// real power series [kn; ...; k0] => kn*S^n + ... + k0*S^0
type Powers = double List
let (+) (ls:Powers) (rs:Powers) =
let rec AddReversed (ls:Powers) (rs:Powers) =
match ( ls, rs ) with
| ( l::ltail, r::rtail ) -> ( l + r ) :: AddReversed ltail rtail
| ([], _) -> rs
| (_, []) -> ls
( AddReversed ( ls |> List.rev ) ( rs |> List.rev) ) |> List.rev
let Evaluate (ks:Powers) ( value:Complex ) =
ks |> List.fold (fun (acc:Complex) (k:double)-> acc * value + Complex.Create(k, 0.0) ) Complex.Zero
最佳答案
你的代码的问题是你的+
的定义实际上隐藏了之前所有的操作符定义,所以F#编译器认为+
只能用于加法Powers
值。这是因为包含 F# 运算符的函数值(使用 let
声明)不支持重载。
但是,如果将 F# 运算符添加为某种类型的 静态成员
,则可以重载它们。这不适用于缩写,因此您需要先将类型声明更改为记录或区分联合(我选择第二个选项)。然后你可以像这样实现重载运算符:
/// real power series [kn; ...; k0] => kn*S^n + ... + k0*S^0
type Powers =
| P of double list
static member (+) (P ls, P rs) =
let rec AddReversed ls rs =
match ( ls, rs ) with
| ( l::ltail, r::rtail ) -> ( l + r ) :: AddReversed ltail rtail
| ([], _) -> rs
| (_, []) -> ls
P (( AddReversed ( ls |> List.rev ) ( rs |> List.rev) ) |> List.rev)
请注意,运算符现在被声明为 Powers
类型的一部分。由于类型是有区别的联合,我需要添加参数的解包(P ls, P rs
),然后再次包装结果。您的 Evaluate
函数将如下所示:
let Evaluate (P ks) ( value:Complex ) =
ks |> List.fold (fun (acc:Complex) (k:double)->
acc * value + Complex.Create(k, 0.0) ) Complex.Zero
再次需要解包值(P ks
),但其余代码不变。
关于F#运算符(operator)重载: (+) for a user defind type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2450515/
我是一名优秀的程序员,十分优秀!