F#函数-预期类型与实际类型不同
我一直在尝试编写一个通用函数“multvec”,它使用u=(u1,u2,…,un)和v=(v1,v2,…,vn)并输出u1*v1+u2*v2+…+联合国*越南。我想我的逻辑基本上是正确的(至少在其他语言中是这样的…),但我一直得到一个:F#函数-预期类型与实际类型不同,f#,f#-3.0,f#-scripting,F#,F# 3.0,F# Scripting,我一直在尝试编写一个通用函数“multvec”,它使用u=(u1,u2,…,un)和v=(v1,v2,…,vn)并输出u1*v1+u2*v2+…+联合国*越南。我想我的逻辑基本上是正确的(至少在其他语言中是这样的…),但我一直得到一个: stdin(11,57): error FS0001: This expression was expected to have type 'a list but here has type 'c list * 'd list -> 'b list
stdin(11,57): error FS0001: This expression was expected to have type
'a list
but here has type
'c list * 'd list -> 'b list
代码如下:问题显然在最后一行的产品调用中。然而,我的印象是基本情况(x*y):[]只会生成一个“a”列表,而不是它实际生成的内容
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 )
如能澄清此错误,将不胜感激!先谢谢你 老实说,您的代码错误多于正确:;-]
- 它不是尾部递归的
- 当
和xs
是单独的参数时,使用ys
函数
- 不完全模式匹配
- 一个分支计算为列表,另一个分支计算为标量
- 所有产品都是手动添加到一起的,但最后一个产品除外,后者有一个
运行单个元素列表–稍微向后;-]李>列表。reduce
let inline multvec xs ys = List.map2 (*) xs ys |> List.sum
请注意,如果性能是一个主要问题,那么可能值得避免使用List.sum
,因为它使用的是检查算法。如果可以使用未经检查的算术,则可以执行以下操作:
let inline multvec xs ys = List.map2 (*) xs ys |> List.reduce (+)
如果您确实想手动执行此操作,有一种方法:
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)
老实说,您的代码错误多于正确:;-]
- 它不是尾部递归的
- 当
和xs
是单独的参数时,使用ys
函数
- 不完全模式匹配
- 一个分支计算为列表,另一个分支计算为标量
- 所有产品都是手动添加到一起的,但最后一个产品除外,后者有一个
运行单个元素列表–稍微向后;-]李>列表。reduce
let inline multvec xs ys = List.map2 (*) xs ys |> List.sum
请注意,如果性能是一个主要问题,那么可能值得避免使用List.sum
,因为它使用的是检查算法。如果可以使用未经检查的算术,则可以执行以下操作:
let inline multvec xs ys = List.map2 (*) xs ys |> List.reduce (+)
如果您确实想手动执行此操作,有一种方法:
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)
要添加到ildjarn的答案中,您可以使用
fold2
计算两个向量的点积(“multvec”),将map2
和reduce
融合到单个函数调用中:
let inline dot xs ys =
let zero = LanguagePrimitives.GenericZero
List.fold2 (fun acc x y -> acc + x * y) zero xs ys
这将避免您创建不必要的临时列表。要添加到ildjarn的答案中,您可以使用
fold2
计算两个向量的点积(“multvec”),将map2
和reduce
融合到单个函数调用中:
let inline dot xs ys =
let zero = LanguagePrimitives.GenericZero
List.fold2 (fun acc x y -> acc + x * y) zero xs ys
这将避免您创建不必要的临时列表。谢谢!您列出的所有方法都非常有效。我想我需要阅读更多的F#介绍文档,因为它与我习惯的其他语言非常不同。谢谢!您列出的所有方法都非常有效。我想我需要阅读更多的F#介绍文档,因为它与我习惯的其他语言有很大的不同。+1我在记事本中工作,忘记了所有关于
fold2
——我想我太依赖Intellisense了-平底船;我也是一个智能感知上瘾者…;)+1我在记事本里工作,忘记了所有的fold2
——我想我太依赖Intellisense了-平底船;我也是一个智能感知上瘾者…;)