Haskell 中的可变变量和 case 语句
Mutable variable and case statement in Haskell
所以我不确定我想要的是否实际上是一个可变变量,但它是类似于它的东西。
我基本上想这样做:
case thing of
True -> p <- func
False -> p <- otherFunc
return Record {program=p, otherFields=oF}
我有什么办法可以做这样的事情吗?我已将我的函数 return 设为一个 IO 记录,因此尝试将 return 放在 case 语句中,但我的最后一行需要 return 它,但事实并非如此。
是的!
let p = case thing of
...
return ...
这是 do
表示法中的语法糖(本身是语法糖)
let p = case thing of
...
in do
...
return ...
您只需移动 case
出现的位置:
p <- case thing of
True -> func
False -> otherFunc
return $ Record {program=p, otherFields=oF}
但这是假设 func
和 otherFunc
具有相同的类型,即 IO Program
,其中 Program
是 p
的任何类型。
你必须这样做,因为语法定义(或多或少)为
case <expr> of
<pattern1> -> <expr1>
<pattern2> -> <expr2>
...
<patternN> -> <exprN>
然而,语法 <pattern> <- <expr>
本身并不是一个表达式,你不能仅仅使用 <-
语法绑定一个名称来获得一个完整的表达式,你必须对它做一些事情然后。将表达式视为 return 一个值,任何值。 <-
语法没有 return 值,它从 monadic 上下文中提取一个值并将其分配给一个名称。这类似于 let x = y
没有 return 值的方式,它只是将一个值绑定到一个名称。 x
和 y
本身有 return 值,但 let x = y
没有。
这就是为什么您不能将 p <- func
单独 单独放在 case 分支中的原因,它必须包含其他内容。但是,如果您的整体案例 expression 具有 return 值,例如 IO Program
,那么您可以使用 <-
.
提取它
几乎所有这些都适用于 let
绑定。相反,如果您的 func
和 otherFunc
函数具有类型 Program
,而不是 IO Program
,那么您可以只执行
let p = case thing of
True -> func
False -> otherFunc
in Record {program=p, otherFields=oF}
或者更简洁
Record {program=(if thing then func else otherFunc), otherFields=oF}
您也可以将 if-then-else
与 monadic 绑定一起使用:
do
p <- if thing then func else otherFunc
return $ Record {program=p, otherFields=oF}
所以我不确定我想要的是否实际上是一个可变变量,但它是类似于它的东西。
我基本上想这样做:
case thing of
True -> p <- func
False -> p <- otherFunc
return Record {program=p, otherFields=oF}
我有什么办法可以做这样的事情吗?我已将我的函数 return 设为一个 IO 记录,因此尝试将 return 放在 case 语句中,但我的最后一行需要 return 它,但事实并非如此。
是的!
let p = case thing of
...
return ...
这是 do
表示法中的语法糖(本身是语法糖)
let p = case thing of
...
in do
...
return ...
您只需移动 case
出现的位置:
p <- case thing of
True -> func
False -> otherFunc
return $ Record {program=p, otherFields=oF}
但这是假设 func
和 otherFunc
具有相同的类型,即 IO Program
,其中 Program
是 p
的任何类型。
你必须这样做,因为语法定义(或多或少)为
case <expr> of
<pattern1> -> <expr1>
<pattern2> -> <expr2>
...
<patternN> -> <exprN>
然而,语法 <pattern> <- <expr>
本身并不是一个表达式,你不能仅仅使用 <-
语法绑定一个名称来获得一个完整的表达式,你必须对它做一些事情然后。将表达式视为 return 一个值,任何值。 <-
语法没有 return 值,它从 monadic 上下文中提取一个值并将其分配给一个名称。这类似于 let x = y
没有 return 值的方式,它只是将一个值绑定到一个名称。 x
和 y
本身有 return 值,但 let x = y
没有。
这就是为什么您不能将 p <- func
单独 单独放在 case 分支中的原因,它必须包含其他内容。但是,如果您的整体案例 expression 具有 return 值,例如 IO Program
,那么您可以使用 <-
.
几乎所有这些都适用于 let
绑定。相反,如果您的 func
和 otherFunc
函数具有类型 Program
,而不是 IO Program
,那么您可以只执行
let p = case thing of
True -> func
False -> otherFunc
in Record {program=p, otherFields=oF}
或者更简洁
Record {program=(if thing then func else otherFunc), otherFields=oF}
您也可以将 if-then-else
与 monadic 绑定一起使用:
do
p <- if thing then func else otherFunc
return $ Record {program=p, otherFields=oF}