简体   繁体   English

Haskell中的可变变量和case语句

[英]Mutable variable and case statement in Haskell

So I'm not sure if what I want is in fact a mutable variable, but it's something likened to it. 因此,我不确定我想要的实际上是否是可变变量,但这与它类似。

I essentially want to do this: 我本质上是想这样做:

case thing of
    True -> p <- func
    False -> p <- otherFunc
return Record {program=p, otherFields=oF}

Any way I can do something like that? 我有什么办法可以做这样的事情吗? I've made my function return an IO Record, so tried just putting the return in the case statement, but my last line needs to return it, and it doesn't. 我已经使函数返回了IO记录,因此尝试仅将return放入case语句中,但是我的最后一行需要返回它,而事实并非如此。

You just need to move where the case occurs: 您只需要移动发生这种case

p <- case thing of
        True -> func
        False -> otherFunc
return $ Record {program=p, otherFields=oF}

But this is assuming that func and otherFunc have the same type, namely IO Program , where Program is whatever type p is. 但这是假设funcotherFunc具有相同的类型,即IO Program ,其中Programp任何类型。

You have to do it this way because the syntax is defined (more or less) as 您必须这样做,因为语法(或多或少)被定义为

case <expr> of
    <pattern1> -> <expr1>
    <pattern2> -> <expr2>
    ...
    <patternN> -> <exprN>

However, the syntax <pattern> <- <expr> is not in itself an expression, you can't just bind a name using the <- syntax to get a complete expression, you have to do something with it afterwards. 但是,语法<pattern> <- <expr>本身并不是表达式,您不能仅使用<-语法绑定名称来获取完整的表达式,然后必须对其进行处理。 Think of expressions as something that return a value, any value at all. 可以将表达式视为可以返回任何值的值。 The <- syntax does not have a return value, it's extracting a value from a monadic context and assigning it to a name. <-语法没有返回值,它是从monadic上下文中提取值并将其分配给名称。 This is similar to how let x = y doesn't have a return value, it's just binding a value to a name. 这类似于let x = y没有返回值,只是将值绑定到名称。 x and y themselves have return values, but let x = y does not. xy本身具有返回值,但let x = y没有。

This is why you can't just put p <- func by itself in a case branch, it would have to have other things with it. 这就是为什么您不能仅将p <- func 本身放在case分支中,而必须将其包含其他内容。 However, if your overall case expression has a return value like IO Program , then you can extract that using <- . 但是,如果您的总体案例表达式具有类似IO Program的返回值,则可以使用<-提取该表达式

Pretty much all of this goes for let bindings as well. 几乎所有这些都用于let绑定。 If instead your func and otherFunc functions have the type Program , instead of IO Program , then you could just do 如果相反,您的funcotherFunc函数的类型为Program ,而不是IO Program ,则您可以执行

let p = case thing of
        True -> func
        False -> otherFunc
in Record {program=p, otherFields=oF}

Or more succinctly 或更简洁

Record {program=(if thing then func else otherFunc), otherFields=oF}

You can use if-then-else with monadic bind as well: 您还可以将if-then-else与monadic绑定一起使用:

do
    p <- if thing then func else otherFunc
    return $ Record {program=p, otherFields=oF}

Yup! 对!

let p = case thing of
   ...
return ...

This is syntax sugar in do notation (itself syntax sugar) for 这是do表示法中的语法糖(本身是语法糖),用于

let p = case thing of
   ...
  in do
       ...
       return ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM