int类型与seq<'a>类型不兼容

时间:2015-12-02 10:08:37

标签: f#

考虑我有以下代码,

let sqx= seq [1; 2; 3; 4;]
let sqy= seq [1; 2; 3; 4;]

let func sqx sqy = seq{ 
         for x in sqx do
            for y in sqy do yield x,y    } 

let cartesian sqx sqy= Seq.map (func sqx) sqy 

cartesian sqx sqy

在最后一行我面对的是erorr:

The type int is not compatible with type seq<'a>

我也曾尝试使用Seq.map2,但问题仍然存在。

2 个答案:

答案 0 :(得分:1)

如果你看一下所涉及的类型,它可能会帮助你理解编译器抱怨的原因。

func的类型为seq<'a> -> seq<'b> -> seq<'a * 'b>。顺便说一句,这也是Seq.zip的类型;考虑将func替换为Seq.zip

Seq.map的类型为('a -> 'b) -> seq<'a> -> seq<'b>

如果你看cartesian,它就会用两个参数调用Seq.map。第二个论点是最容易思考的。从Seq.map的类型,我们知道它必须是seq<'something>

这也意味着func sqx 必须符合'a -> 'b类型,或者更具体地说'something -> 'b

另一方面,func sqx的类型为seq<'b> -> seq<'a * 'b>,因为它已部分应用。换句话说,输入是seq<'b>

必须符合传递给'something -> 'b的{​​{1}}参数,因此Seq.map必须为'something,并且返回类型推断为是seq<'b>。因此,seq<'a * 'b>的总体类型为cartesian

seq<'a> -> seq<#seq<'c>> -> seq<seq<'a * 'c>>的第一个参数必须是cartesian。没关系,因为seq<'a>的类型为sqx

seq<int>的下一个参数必须是cartesian,但seq<#seq<'c>>的类型为sqy。这不是同一类型,这就是seq<int>无法编译的原因。

答案 1 :(得分:0)

我的第一个猜测是你需要像<?php $email = $_SESSION["email"]; $prevq = "Select * FROM `askadoc` WHERE `email` = '$email'"; $result = mysqli_query($conn, $prevq); $prevq = ""; $location = ""; if (mysqli_num_rows($result) > 0): ?> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="home"> <?php while ($row = mysqli_fetch_assoc($result)) : $prevq = $row["question"]; $date = $row["date"]; echo $date; echo "<br>"; echo $prevq; echo "<br>"; endwhile; ?> </div> </div> <?php endif; ?> 这样的东西(这将是你的seq [(1, 1); (1, 2); (1, 3); (1, 4); ...]sqx的笛卡尔积),实际上你已经实现了这个:

sqy

但也许您想将某些功能应用于> func sqx sqy;; val it : seq<int * int> = seq [(1, 1); (1, 2); (1, 3); (1, 4); ...] x in sqx的所有组合?然后可以稍微修改你的代码:

y in sqy

并享受一些乐趣:

let allWith f sqx sqy = 
    seq{ for x in sqx do
         for y in sqy do 
         yield f x y } 

或者你想编写一个能够获取序列序列的笛卡尔积的函数?这更有趣:

> allWith (fun x y -> (x,y)) sqx sqy;;
val it : seq<int * int> = seq [(1, 1); (1, 2); (1, 3); (1, 4); ...]
> allWith (+) sqx sqy;;
val it : seq<int> = seq [2; 3; 4; 5; ...]

这是一个简单的例子:

let rec cartesian (xss : 'a seq seq) =
    if Seq.isEmpty xss then Seq.singleton Seq.empty else
    let first = Seq.head xss
    let rests = cartesian (Seq.tail xss)
    seq { for x in first do
          for xs in rests do
          yield seq { yield x; yield! xs }
    }