wma*_*uez 1 f# f#-scripting f#-3.0
我一直试图写一个curried函数"multvec",它使用u =(u1,u2,...,un)和v =(v1,v2,...,vn)并输出u1*v1 + u2*v2 + ... + un*vn.我认为我的逻辑大多是正确的(至少它会在其他语言中......)但我一直得到一个:
stdin(11,57): error FS0001: This expression was expected to have type
'a list
but here has type
'c list * 'd list -> 'b list
Run Code Online (Sandbox Code Playgroud)
代码如下:问题显然在最后一行的产品调用中.但是,我的印象是基本情况(x*y):: []只会产生一个列表,而不是它实际生成的列表.
let rec multvec xs ys = function
| [ ], [ ] -> failwith "Both lists cannot be empty"
| x::[ ], y::[ ] -> ( x * y )::[ ]
| x::xs, y::ys -> let product = multvec xs ys
( x * y ) + ( List.reduce (+) product )
Run Code Online (Sandbox Code Playgroud)
任何关于此错误的清晰度将不胜感激!先感谢您.
你的代码老实说它的错误比正确:; - ]
functionwhen xs和ys是单独的参数List.reduce在单个元素列表上运行 - 略微向后; - ]这是一个明智的实现,修复了以上所有内容:
let inline multvec xs ys = List.map2 (*) xs ys |> List.sum
Run Code Online (Sandbox Code Playgroud)
请注意,如果性能是主要关注点,那么可能值得避免List.sum,因为它使用了检查算术.如果使用未经检查的算术可以,则可以执行以下操作:
let inline multvec xs ys = List.map2 (*) xs ys |> List.reduce (+)
Run Code Online (Sandbox Code Playgroud)
如果你真的想手动完成这个,这里有一种方法:
let inline multvec xs ys =
let rec impl acc = function
| [], [] -> acc
| x::xs', y::ys' -> impl (x * y + acc) (xs', ys')
| _ -> failwith "lists must be of equal length"
impl LanguagePrimitives.GenericZero (xs, ys)
Run Code Online (Sandbox Code Playgroud)