小编Dav*_*ave的帖子

如何在没有Do符号的情况下书写

我正在玩可组合的失败并设法用签名编写一个函数

getPerson :: IO (Maybe Person)
Run Code Online (Sandbox Code Playgroud)

一个人在哪里:

data Person = Person String Int deriving Show
Run Code Online (Sandbox Code Playgroud)

它的工作原理我用以下的方式编写了它:

import Control.Applicative

getPerson = do
    name <- getLine -- step 1
    age  <- getInt  -- step 2
    return $ Just Person <*> Just name <*> age 
Run Code Online (Sandbox Code Playgroud)

哪里

getInt :: IO (Maybe Int)
getInt = do
    n <- fmap reads getLine :: IO [(Int,String)]
    case n of
        ((x,""):[])   -> return (Just x)
        _ -> return Nothing
Run Code Online (Sandbox Code Playgroud)

我编写此函数的目的是创建可组合的可能失败.虽然我对除了Maybe和IO之外的monad的经验很少,但是如果我有一个更复杂的数据类型以及更多的字段,那么链接计算并不复杂.

我的问题是,如果没有写符号,我将如何重写?由于我无法将值绑定到名称或年龄等名称,因此我不确定从哪里开始.

提问的原因只是为了提高我对(>> =)和(<*>)的理解,并构成失败和成功(不要用难以辨认的单行代码来捣乱我的代码).

编辑:我想我应该澄清一下,"我应该怎么重写getPerson而不用do-notation",我不关心getInt函数的一半.

monads haskell composition

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

如何消除字符串Taversals和列表理解中的成本中心

我正在使用Haskell从生物信息学领域实现一个主题发现算法.我不会进入算法的细节,然后说它的分支和绑定中值字符串搜索.我曾计划通过实现并发方法(以及后来的STM方法)使我的实现更有趣,以便在使用follow标志进行编译后获得多核加速

$ ghc -prof -auto-all -O2 -fllvm -threaded -rtsopts --make main 
Run Code Online (Sandbox Code Playgroud)

并打印配置文件我看到一些有趣的(也许是显而易见的):

COST CENTRE      entries  %time %alloc  
hammingDistance  34677951  47.6   14.7  
motifs           4835446   43.8   71.1  
Run Code Online (Sandbox Code Playgroud)

很明显,如果不进行多核编程,可以获得显着的加速(尽管已经完成了,我只需要找到一些好的测试数据并为此挑选出Criterion).

无论如何,这两个函数都是纯粹的功能,绝不是并发的.他们也做了很简单的事情,所以我很惊讶他们花了这么多时间.这是他们的代码:

data NukeTide = A | T | C | G deriving (Read, Show, Eq, Ord, Enum)

type Motif = [NukeTide] 

hammingDistance :: Motif -> Motif -> Int
hammingDistance [] [] = 0
hammingDistance xs [] = 0 -- optimistic
hammingDistance [] ys = 0 -- optimistic
hammingDistance (x:xs) (y:ys) = case (x == …
Run Code Online (Sandbox Code Playgroud)

optimization profiling haskell bioinformatics branch-and-bound

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

随机数和IO的Haskell递归

对于99个Haskell问题,特别是第23个问题,我需要

"从列表中提取给定数量的随机选择的元素.

示例(在lisp中):

(rnd-select '(a b c d e f g h) 3)
(E D A)
Run Code Online (Sandbox Code Playgroud)

"

我实施的是这样的:

import System.Random
import Control.Monad

removeAt :: [a] -> Int -> [a]
removeAt (x:xs) i
    | i > 0  = x : removeAt xs (i-1)
    | otherwise = xs

rndSelect :: (RandomGen g) => [a] -> Int ->  g -> IO [a]
rndSelect _ 0 _ = return []
rndSelect xs n gen = do
    let (pos, newGen) = randomR (0, …
Run Code Online (Sandbox Code Playgroud)

io recursion haskell

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

使用带有STM和确定性IO的Par monad

我正在编写一份报告,其中我使用STM包实现了并发多核分支和绑定算法,我遇到了一个问题.

使用STM的实现显然在IO monad中,因为它既使用STM的'atomically'和Concurrent的'forkIO',但它是确定性的.尽管使用了共享内存变量,但对于同一输入,函数的最终结果将始终相同.

我的问题是,除了'unsafePerformIO'之外,在退出IO时我有哪些选择?我是否应该尝试将其从IO monad中删除,因为使用多个内核可能会影响其他并发代码,这些代码对确定性没有相同的保证.

我听说过Par monad包(尽管没有使用它),但STM存在于IO monad中,为了获得线程安全的全局变量,我唯一替代STM的是MVars(我知道),也存在于IO monad中.

parallel-processing monads concurrency haskell stm

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