标签: do-notation

在Scala中等效的Haskell标记或F#计算表达式?

F#Computation Expressions允许隐藏厚层语法糖背后的一元语法的复杂性.Scala中是否有类似的东西?

我认为这是为了理解......

例:

val f = for {
  a <- Future(10 / 2) // 10 / 2 = 5
  b <- Future(a + 1)  //  5 + 1 = 6
  c <- Future(a - 1)  //  5 - 1 = 4
 } yield b * c         //  6 * 4 = 24

 val result = f.get
Run Code Online (Sandbox Code Playgroud)

但它确实感觉不对.有更好的语法吗?

例如,你可以拥有哈斯克尔

    main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode
          toHandle   <- getAndOpenFile "Copy to: " WriteMode 
          contents   <- hGetContents fromHandle …

monads f# haskell scala do-notation

6
推荐指数
1
解决办法
1327
查看次数

返回从monad中提取的元素; 多余?

对于所有表现良好的Monads,以下两种flatten等效实现是否相同?

flatten1 xss = do
    xs <- xss
    x <- xs
    return x

flatten2 xss = do
    xs <- xss
    xs
Run Code Online (Sandbox Code Playgroud)

monads haskell do-notation

6
推荐指数
2
解决办法
183
查看次数

用do-notation重写haskell列表理解

我读过" 了解你一个Haskell",Haskell中的列表理解可以改写为monadic join或(实际上是相同的)do-notation.

但是,当我尝试重写以下代码时(生成所有可能的列表,其中包含给定列表中的每个元素):

c :: [[a]] -> [[a]]
c []     = [[]]
c (x:xs) = [a:b | a <- x, b <- c xs]
Run Code Online (Sandbox Code Playgroud)

以这种方式:

d :: [[a]] -> [[a]]
d []     = [[]]
d (x:xs) = do
              a <- x
              b <- d xs
              return a:b
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Couldn't match type `a' with [a]
    `a' is a rigid type variable bound by
        the type signature for d :: [[a]] -> [[a]] 
Expected type: [[a]]
  Actual type: …
Run Code Online (Sandbox Code Playgroud)

haskell list-comprehension do-notation

6
推荐指数
2
解决办法
1228
查看次数

重构使用Reader monad的Haskell函数

我有一些看起来像这样的代码,忽略了与我的问题无关的所有代码:

import qualified Control.Monad.Reader as Reader

data FooEnv = FooEnv { bar :: Int -> Int }
type FooReader = Reader.Reader FooEnv

foo :: Int -> FooReader String
foo i = Reader.liftM show $ bar' i
  where
    bar' i' = do
      bar'' <- Reader.asks bar
      return $ bar'' i'
Run Code Online (Sandbox Code Playgroud)

有没有办法重构这个?具体来说,嵌套bar'函数最让我困扰.这可以浓缩成一行吗?

monads refactoring haskell do-notation reader-monad

6
推荐指数
1
解决办法
217
查看次数

Haskell - 奇怪的阻止行为

在阅读关于MonadPlusHaskell Wikibook时,我发现以下函数基本上采用a 和a 并且如果这样的char与字符串头相等则返回:CharStringJust (char,tail)Nothing

char :: Char -> String -> Maybe (Char, String)
char c s = do
  let (c':s') = s
  if c == c' then Just (c, s') else Nothing
Run Code Online (Sandbox Code Playgroud)

并且他们解释说let (c':s') = s不会产生异常,因为它在一个do块中会评估Nothing模式何时失败,但事实并非如此,因为当我尝试它时:

*Main> char 'a' ""
*** Exception: exercice2.hs:5:7-17: Irrefutable pattern failed for pattern (c' : s')
Run Code Online (Sandbox Code Playgroud)

所以我不得不重写它:

char' :: Char -> String -> Maybe (Char, String)
char' _ [] = …
Run Code Online (Sandbox Code Playgroud)

haskell pattern-matching do-notation

6
推荐指数
1
解决办法
107
查看次数

做符号和绑定签名

我是Haskell和函数式编程的新手,我想知道为什么这样的例子("嵌套循环")有效:

do
  a <- [1, 2, 3]
  b <- [4, 5, 6]
  return $ a * 10 + b
Run Code Online (Sandbox Code Playgroud)

下面的一些东西是一种伪Haskell语法,但我希望它能说明我的理解.

这是我的理解,它变成了这样的东西

[1, 2, 3] >>= \a -> 
          ([4, 5, 6] >>= \b -> 
                     return $ b * 10 + a)
Run Code Online (Sandbox Code Playgroud)

我想这个表达方式

[4, 5, 6] >>= \b -> return $ b * 10 + a
Run Code Online (Sandbox Code Playgroud)

生成部分应用函数的列表

[[40 + a], [50 + a], [60 + a]]
Run Code Online (Sandbox Code Playgroud)

连接到

[40 + a, 50 + a, 60 + a]
Run Code Online (Sandbox Code Playgroud)

最后一步,看起来像这样

[1, 2, 3] >>= \a …
Run Code Online (Sandbox Code Playgroud)

monads haskell do-notation

6
推荐指数
1
解决办法
101
查看次数

'do' 块内的守卫 - haskell

我想写一个简单的游戏“猜数字” -n尝试。我想添加一些条件和命中。是否可以在block内使用守卫do

这是我的代码:

game = return()
game n = do putStrLn "guess number: 0-99"
            number<-getLine
            let y = read number
            let x =20
            | y>x = putStrLn "your number is greater than x"
            | y<x = putStrLn "your number is less than x"
            | y==x  putStrLn "U win!!"
            | otherwise = game (n-1)
Run Code Online (Sandbox Code Playgroud)

已经出错

error: parse error on input ‘|’
Run Code Online (Sandbox Code Playgroud)

它可以用一些空白来修复,还是不可能做到?

syntax haskell guard-clause do-notation

6
推荐指数
2
解决办法
1829
查看次数

仅使用monadic绑定语法表示阻止

据我所知,doHaskell中的块只是monadic绑定运算符的某种语法糖.例如,一个人可以转换

main = do f <- readFile "foo.txt"
          print f
          print "Finished"
Run Code Online (Sandbox Code Playgroud)

main = readFile "foo.txt" >>= print >> print "Finished"
Run Code Online (Sandbox Code Playgroud)

是否可以将所有do块转换为绑定语法?例如,f多次使用此块的情况如何:

main = do f <- readFile "foo.txt"
          print $ "prefix " ++ f
          print $ f ++ " postfix"
Run Code Online (Sandbox Code Playgroud)

假设我们在IO monad中,则不可能简单地执行readFile两次计算.如何使用绑定语法表示此示例(如果可能的话)?

我认为使用Control.Monad不是解决方案,因为它在内部使用do块.

我认为可以使用箭头(使用&&&)表达这一点- 也许这只是一个箭头可以用作monads的推广的情况

请注意,这个问题不是关于上面的特殊示例,而是关于在monadic表达式中多次使用计算结果的一般情况print.

monads haskell scope do-notation

5
推荐指数
2
解决办法
228
查看次数

在Haskell标记中生成唯一值

为了生成x86汇编代码,我定义了一个名为的自定义类型X86:

data X86 a = X86 { code :: String, counter :: Integer, value :: (X86 a -> a) }
Run Code Online (Sandbox Code Playgroud)

此类型用于如下所示的标记.这样可以轻松编写用于生成if语句,for循环等的模板...

generateCode :: X86 ()
generateCode = do
  label1 <- allocateUniqueLabel
  label2 <- allocateUniqueLabel
  jmp label1
  label label1
  jmp label2
  label label2
Run Code Online (Sandbox Code Playgroud)

说明定义如下:

jmp :: String -> X86 ()
jmp l = X86 { code = "jmp " ++ l ++ ";\n", counter = 0, value = const () }

label :: String -> X86 ()
label l …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad do-notation

5
推荐指数
1
解决办法
247
查看次数

为什么“ let”语句强制“ applyative do”块要求monad约束?

考虑以下示例:

{-# language ApplicativeDo #-}

module X where

data Tuple a b = Tuple a b deriving Show

instance Functor (Tuple a) where
    fmap f (Tuple x y) = Tuple x (f y)

instance Foldable (Tuple a) where
    foldr f z (Tuple _ y) = f y z

instance Traversable (Tuple a) where
    traverse f (Tuple x y) = do
        y' <- f y
        let t' = Tuple x y'
        return $ t'
Run Code Online (Sandbox Code Playgroud)

看起来不错!但不是:

[1 of 1] Compiling X                ( …
Run Code Online (Sandbox Code Playgroud)

monads haskell ghc do-notation applicative

5
推荐指数
1
解决办法
67
查看次数