标签: do-notation

let语句中的case语句需要什么缩进?

在哈斯克尔工作,发现奇怪的行为,将其剥离为裸骨

这个作品

a :: Bool
a = case True of
    True -> True
    False -> False
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试

b :: IO Bool
b = do
    let b' = case True of
        True -> True
        False -> False
    return b'
Run Code Online (Sandbox Code Playgroud)

我明白了

ghci>:l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:16:14: parse error on input ‘->’
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

所以我试试

c :: IO Bool
c = do
    let c' = case True of
            True -> True
            False -> False …
Run Code Online (Sandbox Code Playgroud)

haskell indentation do-notation

9
推荐指数
2
解决办法
1996
查看次数

Do 表示法和列表 monad

我正在学习哈斯克尔。

\n

我正在尝试查找列表中as与列表元素相加的元素bs,并将元素作为元组返回:

\n
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]\nfindSum2 as bs = [(a, a', b) | a <- as, a' <- as, b <- bs, a + a' == b]\n
Run Code Online (Sandbox Code Playgroud)\n

该代码有效。但为了学习 Haskell,我尝试将其重写为do-notation:

\n
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]\nfindSum2 as bs = do\n  a  <- as\n  a' <- as \n  b  <- bs\n  if a + a' == b then return (a, a', b) \n                 else return ()\n
Run Code Online (Sandbox Code Playgroud)\n

然后类型检查员向我抱怨: …

monads haskell list-comprehension list do-notation

9
推荐指数
2
解决办法
1000
查看次数

符号与let中的模式匹配

我最近在使用threepenny-gui时遇到了一个错误 ,它通过将符号中的模式匹配的代码更改为<-与let符号的模式匹配来解决.

在这两种模式匹配形式之间进行转换时,我是否应该期望改变行为?

具体如下代码:

在IO monad中:

Just events <- Map.lookup elid <$> readMVar sElementEvents
Run Code Online (Sandbox Code Playgroud)

改为:

mevents <- Map.lookup elid <$> readMVar sElementEvents
let Just events = mevents
Run Code Online (Sandbox Code Playgroud)

这是一个提交的链接,为我解决了问题:https: //github.com/Davorak/threepenny-gui/commit/fbf6cbe25875fafdc64f7a111ddebf485b45143b

其他平台细节:os:10.8.5 ghc:7.6.3

编辑:添加了这个发生在IO monad的事实

haskell pattern-matching do-notation threepenny-gui

8
推荐指数
1
解决办法
2589
查看次数

LYAH - 在链接 Writer monad 时理解关于“告诉”的评论

问题在底部以粗体显示。

LYAH 给出了这个使用monaddo符号的例子Writer

import Control.Monad.Writer

logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["number " ++ show x])

multWithLog :: Writer [String] Int
multWithLog = do
              a <- logNumber 3
              b <- logNumber 5
              return (x*y)
Run Code Online (Sandbox Code Playgroud)

定义可以在没有do符号的情况下重写:

multWithLog = logNumber 3 >>= (\x ->
              logNumber 5 >>= (\y ->
              return (x*y)))
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好。

之后,书中介绍了tell,并编辑了这样的定义multWithLog

multWithLog = do
              a <- logNumber 3
              b <- logNumber 5
              tell ["something"]
              return …
Run Code Online (Sandbox Code Playgroud)

monads haskell rewriting do-notation writer-monad

8
推荐指数
1
解决办法
88
查看次数

函数中不一致的 do 符号

为什么允许使用此功能:

-- function 1
myfunc :: String
myfunc = do
  x <- (return True)
  show x
Run Code Online (Sandbox Code Playgroud)

这不是:

-- function 2
myfunc :: String
myfunc = do
  x <- getLine
  show x
Run Code Online (Sandbox Code Playgroud)

编译错误:

Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: String
Run Code Online (Sandbox Code Playgroud)

我明白为什么功能 2 不应该工作,但为什么功能 1 工作呢?

为什么这会起作用:

-- function 3
myfunc = do
  x <- getLine
  return (show x)
Run Code Online (Sandbox Code Playgroud)

我知道它IO String然后返回,但是为什么函数 1 也没有被迫这样做?

monads haskell type-mismatch do-notation

8
推荐指数
2
解决办法
173
查看次数

`do` 关键字是运行块还是将其视为表达式?

文件指出,“运行块地方不能是独立的语句最简单的方法是通过编写do之前”,并提供了下面的例子:

# This dies half of the time 
do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win.";
Run Code Online (Sandbox Code Playgroud)

但是,do似乎不会导致所有块都运行。特别是,它似乎没有运行带有签名的块:

do -> $a = 42 { say "ran with $a"; 0 } or die; say 'done'; # OUTPUT: «done»
Run Code Online (Sandbox Code Playgroud)

那么将do块视为有时会导致它运行的表达式会更好吗?还是乐堂在这里的行为不正确?还是我的理解不正确?

expression rakudo do-notation raku

8
推荐指数
1
解决办法
129
查看次数

添加操作而不将结果更改为重构标记

我想在Haskell中依次组合两个monad动作,丢弃第二个动作产生的任何值,并将参数传递给两个动作.目前我正在使用这样的do-block:

ask = do
  result <- getLine
  putStrLn result
  return result
Run Code Online (Sandbox Code Playgroud)

我本来希望写一点免费和整洁,所以我尝试了这个:

ask' = getLine <* putStrLn
Run Code Online (Sandbox Code Playgroud)

但是,这甚至不进行类型检查,问题是<*不会将第一个动作的结果传递给第二个动作.我希望将操作链接起来>>=,但不会更改结果.类型应该是(a -> m b) -> (a -> m c) -> (a -> m b),但Hoogle没有产生合适的结果.实现此功能组合的操作员是什么?

refactoring haskell pointfree do-notation

7
推荐指数
1
解决办法
91
查看次数

功能组成表示法

对于简单的函数组合,是否有"do notation"语法糖?

(即(.) :: (b -> c) -> (a -> b) -> a -> c)

我希望能够存储一些成分的结果供以后使用(同时仍然继续链.

如果可能的话,我宁愿不使用RebindableSyntax扩展.

我正在寻找这样的东西:

composed :: [String] -> [String]
composed = do
    fmap (++ "!!!")
    maxLength <- maximum . fmap length
    filter ((== maxLength) . length)

composed ["alice", "bob", "david"]
-- outputs: ["alice!!!", "david!!!"]
Run Code Online (Sandbox Code Playgroud)

我不确定这样的事情是否可能,因为早期函数的结果基本上必须通过"通过"maxLength的绑定,但我愿意听到任何其他类似的表达选项.基本上我需要收集信息,因为我通过合成以便以后使用它.

也许我可以用状态monad做这样的事情?

谢谢你的帮助!

编辑

这种事情有点起作用:

split :: (a -> b) -> (b -> a -> c) -> a -> c
split ab bac a = bac (ab a) a

composed …
Run Code Online (Sandbox Code Playgroud)

haskell composition do-notation

7
推荐指数
2
解决办法
307
查看次数

如何有条件地绑定在do块中?

我想在do块中实现以下目标:

do 
  if condition then
    n0 <- expr0
  else
    n0 <- expr0'
  n1 <- expr1
  n2 <- expr2
  return T n0 n1 n2
Run Code Online (Sandbox Code Playgroud)

但是Haskell会给出一个编译错误,除非我这样做:

do 
  if condition then
    n0 <- expr0
    n1 <- expr1
    n2 <- expr2
    return T n0 n1 n2  
  else
    n0 <- expr0'
    n1 <- expr1
    n2 <- expr2
    return T n0 n1 n2 
Run Code Online (Sandbox Code Playgroud)

它看起来很冗长,尤其是当有许多共享的绑定表达式时。如何使其更简洁?

实际上,我正在尝试执行以下操作:

do 
  if isJust maybeVar then
    n0 <- f (fromJust maybeVar)
    n1 <- expr1
    n2 <- expr2
    return (T (Just n0) n1 …
Run Code Online (Sandbox Code Playgroud)

monads haskell bind conditional-statements do-notation

7
推荐指数
2
解决办法
165
查看次数

在 OCaml 中做符号

OCaml 是否与 Haskell 的 Do Notation 等效?

另一种说法 - 有没有一种简单的方法可以更轻松地处理嵌套的 monadic 操作......因为这很烦人:

open Batteries
open BatResult.Infix

let () =
  let out = 
    (Ok("one")) >>=
      (fun a -> 
        let b = Ok("two") in
        b >>= (fun c -> 
          print_endline(a);
          print_endline(c);
          Ok(c)
          )) in
  ignore(out)
  
Run Code Online (Sandbox Code Playgroud)

monads ocaml do-notation

7
推荐指数
2
解决办法
227
查看次数