Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#函数-预期类型与实际类型不同_F#_F# 3.0_F# Scripting - Fatal编程技术网

F#函数-预期类型与实际类型不同

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

我一直在尝试编写一个通用函数“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
代码如下:问题显然在最后一行的产品调用中。然而,我的印象是基本情况(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了-平底船;我也是一个智能感知上瘾者…;)