函数式编程 - 避免匹配表达式中的可变和更改 int 值

Functional Programming - Avoid mutable in match expression and changing int value

我刚开始进行函数式编程。我目前要开始的小项目是一场基本的口袋妖怪对战。

先写代码,再解释。

let choosePokemon () =
    let mutable pokemon = DemoData.schiggy
    let msg = Console.ReadLine()
    match msg with
    | "Schiggy" -> pokemon <- DemoData.schiggy
    | "Pikachu" -> pokemon <- DemoData.pikachu
    | "Kleinstein" -> pokemon <- DemoData.kleinstein
    | "Karpador" -> pokemon <- DemoData.karpador 
    pokemon

我目前正在要求人们输入口袋妖怪的名称,如果它与预定义的集合(Schiggy、Pikachu、Kleinstein 或 Karpador)匹配,它就会为他们提供相应的口袋妖怪。或者它给他们默认的口袋妖怪。

我目前正在创建它,然后再将它与“let mutable pokemon = DemoData.schiggy”匹配。我不想要那个。我只想根据它的名字分配它。

如果我可以不用那条线,我会避免让它可变,这是我无论如何都不想要的。

追加问题:宝可梦互相攻击时HP会降低

面对不断变化的 int 值时,如何避免使用可变 int?

提前致谢:)

只是 return 来自 match 的结果 - 无需声明变量:

let choosePokemon () =
    let msg = Console.ReadLine()
    match msg with
    | "Schiggy" -> DemoData.schiggy
    | "Pikachu" -> DemoData.pikachu
    | "Kleinstein" -> DemoData.kleinstein
    | "Karpador" -> DemoData.karpador

函数仍然不纯,但是,因为它执行 I/O (Console.ReadLine)...

它也是 partial,因为它会在匹配的四个字符串以外的任何其他输入上崩溃。即使是拼写错误和大小写错误也会引发异常。

一个更健壮的纯函数应该是这样的:

let choosePokemon (input : string) =
    match input.Trim().ToUpperInvariant () with
    | "PIKACHU"    -> DemoData.pikachu
    | "KLEINSTEIN" -> DemoData.kleinstein
    | "KARPADOR"   -> DemoData.karpador
    | _            -> DemoData.schiggy

与执行 I/O 的 OP 相反,此版本是 pure function,因为没有非确定性行为。它也是总数,因为它 returns schiggy 作为默认值。

要获得要求用户输入值的行为,请将不纯的 Console.ReadLine 操作与纯 choosePokemon 函数组合:

Console.ReadLine >> choosePokemon