Combining multiple functions

扶醉桌前 提交于 2020-01-04 01:55:47

问题


I'm trying to make a DNA transcription program but I'm having trouble with the way I'm doing it, I'm sure there's an easier way to do this but this was the first thing that came to my head but it's not working the way I want it to.

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)

Here's the output:

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

I figure this is because the transc replaces the A, then checks the whole String and replaces the T, etc etc Any tips? Thanks in advance!


回答1:


You should make one function which handles all of the Char -> Char conversions at once.

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"

To make this even safer, you could make it return a Maybe [Char] instead. The lookup function can also be used instead of using a custom mapping function.

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



回答2:


@4castle's answer shows the right direction.

Since OP's problem has been solved i believe it would worth to show how to make it more efficient by using Data.Map for the look ups. Also by using a foldl we may skip the reversing job as well.

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"


来源:https://stackoverflow.com/questions/47146630/combining-multiple-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!