相关疑难解决方法(0)

Haskell - 应用将函子返回到函子上的函数

假设我有两个函数fg它们都接受常规值并返回一个Either像这样的值:

g :: a -> Either x b
f :: b -> Either x c
Run Code Online (Sandbox Code Playgroud)

我如何将两者链接在一起以获得类似的东西f . g

我想出的最佳解决方案是创建一个名为的辅助函数applyToRight,其工作方式如下

applyToRight :: (a -> Either x b) -> Either x a -> Either x b
applyToRight f x =
  case x of
    Left a -> Left a
    Right b -> f b
Run Code Online (Sandbox Code Playgroud)

这样我就可以做

applyToRight f (g a)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我专门谈论Either,但我认为这个问题可以推广到所有应用函子。处理这个问题的最优雅的方法是什么?

haskell composition functor function-composition applicative

3
推荐指数
1
解决办法
124
查看次数

如何加入两个 Haskell IO monad

以下(工作)Haskell 程序输出随机拼写:

import System.Random

spells =
  [ "Abracadabra!"
  , "Hocus pocus!"
  , "Simsalabim!"
  ]

main :: IO()
main = do
  spell <- (spells !!) <$> randomRIO (0, length spells - 1)
  putStrLn spell
Run Code Online (Sandbox Code Playgroud)

然而,这个变量spell是非常无用的。它存储从法术列表中选择的随机字符串,但随后会立即传递给putStrLn函数并且不再使用。我尝试将两个 IO 操作合并为一行,如下所示:

main = putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

    • Couldn't match type ‘IO ()’ with ‘()’
      Expected type: Int -> ()
        Actual type: Int -> IO ()
    • In the first argument of ‘(<$>)’, …
Run Code Online (Sandbox Code Playgroud)

random monads haskell io-monad

3
推荐指数
2
解决办法
232
查看次数

为什么列出monad按顺序组合?

我正在阅读列表monad并遇到:

[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)  
Run Code Online (Sandbox Code Playgroud)

它产生

[(1,'a'),(1,'b'),(2,'a'),(2,'b')]
Run Code Online (Sandbox Code Playgroud)

这是我理解的方式:

隐含括号是:

([1,2] >>= \n -> ['a','b']) >>= (\ch -> return (n,ch))
Run Code Online (Sandbox Code Playgroud)

([1,2] >>= \n -> ['a','b']) 应该给 [('a',1),('b',1),('a',2),('b',2)]

因为

instance Monad [] where  
  return x = [x]  
  xs >>= f = concat (map f xs)   -- this line
  fail _ = []
Run Code Online (Sandbox Code Playgroud)

所以concat (map f xs)concat (map (\n -> ['a','b']) [1,2])应当产生[('a',1),('b',1),('a',2),('b',2)]-实际输出的正好相反.

然后我不明白>>= (\ch -> return (n,ch))部分 - 我认为 …

syntax monads haskell list parentheses

2
推荐指数
1
解决办法
128
查看次数

`bind`相当于join(fmap fm)?

这个问题的优秀答案演示了如何用以下方式编写和:bindjoinfmap

(>>=) :: m v -> (v -> m w) -> m w

他说:"如果你有制定av的策略,并且每个va后续策略都要生成aw,那么你就有了制作w的策略".我们如何在加入方面捕获它?

mv >>= v2mw = join (fmap v2mw mv)

但是,我不知道如何v2mw,其中有一个类型的a -> m b,以第一个参数类型检查fmap.

fmap :: Functor f => (a -> b) -> f a -> f b

monads haskell

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

了解单子函数的组成

我正在从“学习Haskell为伟大!”一书中学习单子。由Miran Lipovaca撰写。我试图理解单子的结合律。本质上,法律规定,当您使用拥有一元函数应用程序链时>>=,如何嵌套它们无关紧要。

以下代码使人们能够将type函数的结果传递给type a -> m b函数b -> m c

(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)
Run Code Online (Sandbox Code Playgroud)

但是,对于以下示例:

ghci> let f x = [x, -x]
ghci> let g x = [x*3, x*2]
ghci> let h = f <=< g
ghci> h 3
[9, -9, 6, -6]
Run Code Online (Sandbox Code Playgroud)

f xg x两个功能?看来它们是具有不同x值而不是函数的列表。该行在 …

monads haskell list function-composition kleisli

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

可以将((&gt;&gt; =)`重新声明为((a-&gt; mb)-&gt; ma-&gt; mb`吗?

在Haskell Monad中声明为

class   Applicative m   =>  Monad   m   where
    return  ::  a   ->  m   a
    (>>=)   ::  m   a   ->  (a  ->  m   b)  ->  m   b
    return  =   pure
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以将bind运算符重新声明为

(>>=)   ::  (a  ->  m   b)  ->  m   a   ->  m   b
Run Code Online (Sandbox Code Playgroud)

第二个声明使将(>>=)type a -> m b的函数映射到type 的函数m a -> m b更清晰,而原始的声明却使它的含义更不清楚,是否正确?

声明的更改是否会使某些事情变为可能,甚至是不可能,或者只需要对使用monad进行一些更改(Haskell程序员似乎可以接受)?

谢谢。

monads haskell

-2
推荐指数
1
解决办法
211
查看次数