着色问题:
您好,我试图实现一个bool函数,当颜色可以扩展到某个国家/地区时返回true,否则返回false但是我在使用集合时遇到问题,因为我们无法对它们进行模式匹配。
我的代码:
type Country = string;;
type Chart = Set<Country*Country>;;
type Colour = Set<Country>;;
type Colouring = Set<Colour>;;
(* This is how you tell that two countries are neghbours. It requires a chart.*)
let areNeighbours ct1 ct2 chart =
Set.contains (ct1,ct2) chart || Set.contains (ct2,ct1) chart;;
(* val areNeighbours :
ct1:'a -> ct2:'a -> chart:Set<'a * 'a> -> bool when 'a : comparison
*)
(* The colour col can be extended by the country ct when they are no neighbours
according to chart.*)
let canBeExtBy (col:Colouring) (ct:Country) (chart:Chart) = col |> Set.fold (fun x -> (if (areNeighbours x ct chart) then true else false))
预期结果:根据图表中定义的邻域,我们需要检查ct是否是col中任何国家/地区的邻居(假设col中有国家/地区)。 所以,如果
chart = set
[("Andorra", "Benin"); ("Andorra", "Canada"); ("Andorra", "Denmark");
("Benin", "Canada"); ("Benin", "Denmark"); ("Canada", "Denmark");
("Estonia", "Canada"); ("Estonia", "Denmark"); ("Estonia", "Finland");
...]
并且
col = set
["Andorra"]
当canBeExt
安道尔与这些国家/地区共享边界时,ct = "Benin" or "Canada" or "Denmark" etc...
应该返回false,因此它们不能与Andora颜色相同。
显然我在canBeExtBy中有一个类型错误,因为我试图返回一个bool并且它期待&#39; a:着色。 我不知道如何实施它。
感谢您的帮助!
答案 0 :(得分:3)
这个怎么样?
type Country = string
type Neighbours = Set<Country*Country>
type SharesColour = Set<Country>
let areNeighbours (ns : Neighbours) (ct1 : Country) (ct2 : Country) : bool =
Set.contains (ct1,ct2) ns || Set.contains (ct2,ct1) ns
let canShareColour (ns : Neighbours) (ct : Country) (s : SharesColour) : bool =
s |> Seq.exists (areNeighbours ns ct) |> not
let neighbours : Neighbours =
set [|
("Andorra", "Benin") ; ("Andorra", "Canada") ; ("Andorra", "Denmark");
("Benin" , "Canada") ; ("Benin" , "Denmark"); ("Canada" , "Denmark");
("Estonia", "Canada") ; ("Estonia", "Denmark"); ("Estonia", "Finland");
|]
let sharesColour : SharesColour =
set [|
"Andorra"
|]
[<EntryPoint>]
let main argv =
printfn "%A" <| canShareColour neighbours "Estonia" sharesColour
printfn "%A" <| canShareColour neighbours "Benin" sharesColour
0
将名称更改为对我更有意义的内容。你可能不同意。
答案 1 :(得分:3)
要检查集合中的任何元素是否满足给定条件:fold
不是exists
的作业,而是forall
或 let fornone f = Set.forall (f >> not)
let doesnotexist f = Set.exists f >> not
的适当否定。
fold
会做,如FuleSnabel的回答所示。但是,当然可以从 let fornone f = Set.fold (fun s -> f >> not >> (&&) s) true
let doesnotexist f = Set.fold (fun s -> f >> (||) s) false >> not
构建这些函数,尽管除了作为currying,函数组合和pointfree风格的例证之外,没有人会这样做。
background