小编Ret*_*Fun的帖子

有没有更可读的方法来重写这个纯函数来使用Writer Monad?

我使用列表推导编写了一个递归算法来执行递归.我认为我的代码清晰易读,其产生的结果是正确的.

但是,我发现很难理解我的代码在某些输入上的性能.我认为使用Writer monad将一些日志记录放入我的代码中会很有用.

我发现将非monadic代码转换为monadic非常困难.最终我得到它编译并正确运行,但monadic代码比原始代码更难理解.

原始问题太复杂了,无法在这里解释,所以我写了一个玩具示例,显示非monadic和monadic方法,但实际上并没有计算任何有用的东西!

所以我的问题是:有没有更好的方法来编写函数fMonadic,这样它更具可读性?

import Control.Monad (forM)
import Control.Monad.Writer (Writer, runWriter, tell)

fun :: Int -> [[Int]] -> [[Int]]
fun a b = map (map (a +)) b

fNonMonadic :: [[Int]] -> [[Int]]
fNonMonadic [] = [[]]
fNonMonadic (first : rest) =
    [ first ++ s
    | e <- first
    , s <- fNonMonadic $ fun e rest]

fMonadic :: [[Int]] -> Writer [String] [[Int]]
fMonadic [] = do
    tell ["base case"]
    return [[]]
fMonadic (first : rest) …
Run Code Online (Sandbox Code Playgroud)

monads haskell

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

在Haskell中使用IO模仿Python生成器

这是关于如何在Haskell中执行某些操作的问题,这在Python3中很容易实现.

我有一个使用生成器的Python3程序,如下所示:

def gen(filename):
    for line in open(filename):
        line = line.rstrip()
        print(f"From {filename} about to yield the line {line}")
        yield line
        print(f"From {filename} recently yielded the line {line}")
        if "." in line:
            yield from gen(line)

for line in gen("a.txt"):
    print(f"Main program has {line}")
Run Code Online (Sandbox Code Playgroud)

如果我给它一个输入文件a.txt包含以下内容:

First line of a
b.txt
Third line of a
Run Code Online (Sandbox Code Playgroud)

和另一个包含以下内容的输入文件b.txt:

First line of b
Second line of b
Run Code Online (Sandbox Code Playgroud)

那么输出,正如我所料,是:

From a.txt about to yield the line First line of a
Main program has First line of …
Run Code Online (Sandbox Code Playgroud)

haskell

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

可以在不使用可变变量的情况下编码吗?

考虑以下(非常沉闷)游戏: - 玩家A认为1到100之间的数字. - 玩家B允许5次尝试猜测该数字.玩家A将对每个猜测做出"太大","太小"或"正确"的回应.

我想在Haskell中模拟这个,当然这很简单.但是为了让事情变得有趣,我想以玩家B不能"欺骗"的方式编写代码.这意味着两件事: - 玩家B代码不允许查看密码的正确值.播放器A代码为播放器B代码提供了一个函数,用于检查其猜测. - 不允许玩家B代码调用该函数超过五次.不知何故,播放器A代码必须保持调用函数的次数.

这在使用私有可变变量的OO语言中很容易实现.

在Haskell中,我使用IORef对其进行编码以记录调用次数.那很好,我认为我的解决方案是正确的.但我的问题是:

"如果没有IORef或者类似的话,这可以在Haskell中完成吗?是否有一个我错过的纯功能解决方案?"

这是我的Haskell代码:

import Data.IORef (newIORef, readIORef, writeIORef)
import System.Random (randomRIO)

lowest = 1
highest = 100
maxtries = 5

playerA :: IO (Int -> IO (Maybe Ordering))
playerA = do
    secret <- randomRIO (lowest, highest)
    print ("Secret", secret)
    tries <- newIORef maxtries
    return $ \ guess -> do
        t <- readIORef tries
        if t == 0 then
            return Nothing
        else do
            writeIORef tries $ t - 1
            return …
Run Code Online (Sandbox Code Playgroud)

haskell

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

标签 统计

haskell ×3

monads ×1