我正在玩可组合的失败并设法用签名编写一个函数
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函数的一半.
我正在使用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
对于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) 我正在编写一份报告,其中我使用STM包实现了并发多核分支和绑定算法,我遇到了一个问题.
使用STM的实现显然在IO monad中,因为它既使用STM的'atomically'和Concurrent的'forkIO',但它是确定性的.尽管使用了共享内存变量,但对于同一输入,函数的最终结果将始终相同.
我的问题是,除了'unsafePerformIO'之外,在退出IO时我有哪些选择?我是否应该尝试将其从IO monad中删除,因为使用多个内核可能会影响其他并发代码,这些代码对确定性没有相同的保证.
我听说过Par monad包(尽管没有使用它),但STM存在于IO monad中,为了获得线程安全的全局变量,我唯一替代STM的是MVars(我知道),也存在于IO monad中.
haskell ×4
monads ×2
composition ×1
concurrency ×1
io ×1
optimization ×1
profiling ×1
recursion ×1
stm ×1