在哈斯克尔工作,发现奇怪的行为,将其剥离为裸骨
这个作品
a :: Bool
a = case True of
    True -> True
    False -> False
但是,当我尝试
b :: IO Bool
b = do
    let b' = case True of
        True -> True
        False -> False
    return b'
我明白了
ghci>:l test.hs
[1 of 1] Compiling Main             ( test.hs, interpreted )
test.hs:16:14: parse error on input ‘->’
Failed, modules loaded: none.
所以我试试
c :: IO Bool
c = do
    let c' = case True of
            True -> True
            False -> False …我正在学习哈斯克尔。
\n我正在尝试查找列表中as与列表元素相加的元素bs,并将元素作为元组返回:
findSum2 :: [Int] -> [Int] -> [(Int,Int,Int)]\nfindSum2 as bs = [(a, a', b) | a <- as, a' <- as, b <- bs, a + a' == b]\n该代码有效。但为了学习 Haskell,我尝试将其重写为do-notation:
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然后类型检查员向我抱怨: …
我最近在使用threepenny-gui时遇到了一个错误 
 ,它通过将符号中的模式匹配的代码更改为<-与let符号的模式匹配来解决.
在这两种模式匹配形式之间进行转换时,我是否应该期望改变行为?
具体如下代码:
在IO monad中:
Just events <- Map.lookup elid <$> readMVar sElementEvents
改为:
mevents <- Map.lookup elid <$> readMVar sElementEvents
let Just events = mevents
这是一个提交的链接,为我解决了问题:https: //github.com/Davorak/threepenny-gui/commit/fbf6cbe25875fafdc64f7a111ddebf485b45143b
其他平台细节:os:10.8.5 ghc:7.6.3
编辑:添加了这个发生在IO 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)
定义可以在没有do符号的情况下重写:
multWithLog = logNumber 3 >>= (\x ->
              logNumber 5 >>= (\y ->
              return (x*y)))
到现在为止还挺好。
之后,书中介绍了tell,并编辑了这样的定义multWithLog:
multWithLog = do
              a <- logNumber 3
              b <- logNumber 5
              tell ["something"]
              return …为什么允许使用此功能:
-- function 1
myfunc :: String
myfunc = do
  x <- (return True)
  show x
这不是:
-- function 2
myfunc :: String
myfunc = do
  x <- getLine
  show x
编译错误:
Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: String
我明白为什么功能 2 不应该工作,但为什么功能 1 工作呢?
为什么这会起作用:
-- function 3
myfunc = do
  x <- getLine
  return (show x)
我知道它IO String然后返回,但是为什么函数 1 也没有被迫这样做?
该文件指出,“运行块地方不能是独立的语句最简单的方法是通过编写do之前”,并提供了下面的例子:
# This dies half of the time 
do { say "Heads I win, tails I die."; Bool.pick } or die; say "I win.";
但是,do似乎不会导致所有块都运行。特别是,它似乎没有运行带有签名的块:
do -> $a = 42 { say "ran with $a"; 0 } or die; say 'done'; # OUTPUT: «done»
那么将do块视为有时会导致它运行的表达式会更好吗?还是乐堂在这里的行为不正确?还是我的理解不正确?
我想在Haskell中依次组合两个monad动作,丢弃第二个动作产生的任何值,并将参数传递给两个动作.目前我正在使用这样的do-block:
ask = do
  result <- getLine
  putStrLn result
  return result
我本来希望写一点免费和整洁,所以我尝试了这个:
ask' = getLine <* putStrLn
但是,这甚至不进行类型检查,问题是<*不会将第一个动作的结果传递给第二个动作.我希望将操作链接起来>>=,但不会更改结果.类型应该是(a -> m b) -> (a -> m c) -> (a -> m b),但Hoogle没有产生合适的结果.实现此功能组合的操作员是什么?
对于简单的函数组合,是否有"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!!!"]
我不确定这样的事情是否可能,因为早期函数的结果基本上必须通过"通过"maxLength的绑定,但我愿意听到任何其他类似的表达选项.基本上我需要收集信息,因为我通过合成以便以后使用它.
也许我可以用状态monad做这样的事情?
谢谢你的帮助!
编辑
这种事情有点起作用:
split :: (a -> b) -> (b -> a -> c) -> a -> c
split ab bac a = bac (ab a) a
composed …我想在do块中实现以下目标:
do 
  if condition then
    n0 <- expr0
  else
    n0 <- expr0'
  n1 <- expr1
  n2 <- expr2
  return T n0 n1 n2
但是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 
它看起来很冗长,尤其是当有许多共享的绑定表达式时。如何使其更简洁?
实际上,我正在尝试执行以下操作:
do 
  if isJust maybeVar then
    n0 <- f (fromJust maybeVar)
    n1 <- expr1
    n2 <- expr2
    return (T (Just n0) n1 …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)
  
do-notation ×10
haskell ×8
monads ×5
bind ×1
composition ×1
expression ×1
indentation ×1
list ×1
ocaml ×1
pointfree ×1
raku ×1
rakudo ×1
refactoring ×1
rewriting ×1
writer-monad ×1