结合多种功能

时间:2017-11-06 22:06:44

标签: haskell

我正在尝试制作DNA转录程序,但我对自己的方式遇到了麻烦,我确定这是一种更简单的方法这是我头脑中的第一件事,但它没有按照我想要的方式工作。

dnaToRna :: [Char] -> [Char]
dnaToRna [] = []
dnaToRna xs = reverse(transc xs)
    where transc = (replaceA . replaceT . replaceC . replaceG)
replaceA = map(\c -> if c == 'A' then 'U' else c)
replaceT = map(\c -> if c == 'T' then 'A' else c)
replaceC = map(\c -> if c == 'C' then 'G' else c)
replaceG = map(\c -> if c == 'G' then 'C' else c)

这是输出:

*Main> let seq = "AAATGTTAGTACACTAAGG"
*Main> dnaToRna seq
"GGUUUGUGUUGUUUGUUUU"

我认为这是因为transc替换了A,然后检查整个String并替换了T等 有小费吗? 提前谢谢!

2 个答案:

答案 0 :(得分:3)

您应该制作一个能够同时处理所有Char -> Char次转化的功能。

dnaToRna :: [Char] -> [Char]
dnaToRna = reverse . map transc
  where
    transc 'A' = 'U'
    transc 'T' = 'A'
    transc 'C' = 'G'
    transc 'G' = 'C'
    transc _   = error "Invalid DNA molecule"

为了使这更安全,您可以让它返回Maybe [Char]。也可以使用lookup函数代替使用自定义映射函数。

dnaToRna :: [Char] -> Maybe [Char]
dnaToRna = mapM (`lookup` zip "ATCG" "UAGC") . reverse

答案 1 :(得分:0)

@ 4castle的答案显示了正确的方向。

由于OP的问题已经解决,我相信通过使用Data.Map进行查找可以证明如何提高效率。另外,通过使用foldl,我们也可以跳过撤销工作。

import qualified Data.Map.Lazy as M

dna2rna :: String -> String
dna2rna = foldl (\r c -> (M.findWithDefault '-' c m) : r) ""
          where m  = M.fromList $ zip "ATCG" "UAGC"

*Main> dna2rna "AAATGTTAGTACACTAAGG"
"CCUUAGUGUACUAACAUUU"