haskell 字节串中的模式不匹配
pattern doesn't match in haskell bytestring
我正在使用 Haskell(特别是 bytestrings
)编写 DNA 翻译器。我有以下代码:
import Data.Maybe
import Data.Monoid ((<>))
import System.Environment
import qualified Data.ByteString as B
import Data.ByteString.Lazy.Char8 (ByteString, singleton, splitWith)
import qualified Data.ByteString.Lazy as LB
-- Extract DNA sequence from fasta file
xtractDNA :: [ByteString] -> Maybe ByteString
xtractDNA dna = Just (LB.concat dna)
--xtractDNA = foldr ((<>) . Just) Nothing
-- Reverse Complement DNA
compStrand :: Maybe ByteString -> Maybe ByteString
compStrand = foldr ((<>) . compPairs) Nothing
where
compPairs nt | nt == (singleton 'A') = Just (singleton 'T')
| nt == (singleton 'T') = Just (singleton 'A')
| nt == (singleton 'G') = Just (singleton 'C')
| nt == (singleton 'C') = Just (singleton 'G')
| otherwise = Nothing
main :: IO ()
main = do
putStrLn "Welcome to volcano"
let fname = "/home/trinix/Development/hs_devel/local_data/shbg.fasta"
fid <- LB.readFile fname
let dna = LB.concat $ tail (LB.splitWith (==10) fid)
--putStrLn $ show (LB.length (head dna))
let dsDna = compStrand (Just dna)
print dsDna
当我执行时,我得到 Nothing
作为答案。部分输入为
"AATTCTCCATGTGCTTGGATCGTGGGGAAGATGTGATTAAGGTCTAAGGTATGTCTTCCACCAGACAACGGACACAGTCAATTAGAAGCTGGGTAAAGGGGTCTCTCCTGCGGAGCGGGGAGCGCCAAGCCAGGGACAATAATGGCCTGAAGTTCATTCTCCCGGAGATGGGGGTAGAAGCAGGTGCAGGTGCCTTAGAGGGGTCAAAAATAAGAGGAACAGGGTTCACTCTAAGCGGTCTCCCAGGGAAGGCTGCGGGTTGGAGCAAGGGTCCAAGATTCTAAGGGCCAGGACTCAGCTCCAGAAGCTCGATCCCGCCCCACGCGTTCCTGCTCCGGCCAGGGGAGGGGGCTAAGGACCGGCGTCCCCAGTCGGCGCGCCGTCTCACCTTGTAGAAGGCCCCGTTGGAGCCGCGCACCTCGACGGGCAGTCCCGGCTCCACATCCCCCCCAGAGGCCAGGCCGCCCATGGCGCCGCCACCGCCTCCGACTCCCCCGGCGGCGGCTGCAGCAGCAGTCTGAGTGCGGGCCGGGCCAGGCCCCCGGCGTCTCCCCGGAGGAGGAGCCGGAGGGGGAGCCGCGGGGGGCGGGAGCCGGGCCGGCCCCACGGCGGCCCTGCCACAGCCAACGAGCAGGGGGCCGGGGCCGGGCCGCTCCCCGTCCGCCGCCGCCGCCTTGGTCTCCGCC...ACAAGGTCAGAGGCTGGATGTGGACCAGGCCCTGAACAGAAGCCATGAGATCTGGACTCACAGCTGCCCCCAGAGCCCAGGCAATGGCACTGACGCTTCCCATTAAAGCTCCACCTAAGAACCCCC"
我怀疑我的模式匹配守卫有问题。我怎样才能弄清楚并解决这个问题?任何见解将不胜感激。
compStrand
是一个很奇怪的函数。当你只传递一个 Just 时,为什么它使用 Maybe ByteString 而不是实际的 ByteString?为什么它会做这种古怪的 foldr ((<>) . compPairs) Nothing
事情,这只是 (>>= compPairs)
的一个非常难以阅读的重新实现?
main
不是很清楚:如果您的输入是 GATC 字符串,为什么要在第一个字节等于 10 时拆分?为什么它不使用您为其编写的 xtractDNA
函数?
解决这些问题将使函数更简单,您可以更轻松地自行调试。但我会注意到,你的 compStrand
函数似乎只对单例字符串起作用,但你似乎向它传递了一个大小未知的字符串。
您正在使用 foldr
作为 Foldable
和 Maybe
,而不是 ByteString
。因此它将检查 Maybe a
。如果它是 Just
它将调用 comPairs
与 整个 ByteString
DNA,否则它将 return Nothing
.
你的 comPairs
将 return Nothing
用于任何 ByteString
是空的或有两个或更多字节,因此它 returns Nothing
.
您可以使用 mapM :: Monad m => (a -> m b) -> [a] -> m [b]
构建 Maybe [Word8]
,然后将其转换回 ByteString
:
import Data.ByteString.Lazy.Char8 (ByteString, pack, unpack)
compStrand :: Maybe ByteString -> Maybe ByteString
compStrand = (>>= fmap pack . mapM comPairs . unpack)
where comPairs 'A' = Just 'T'
comPairs 'C' = Just 'G'
comPairs 'G' = Just 'C'
comPairs 'T' = Just 'A'
comPairs _ = Nothing
我正在使用 Haskell(特别是 bytestrings
)编写 DNA 翻译器。我有以下代码:
import Data.Maybe
import Data.Monoid ((<>))
import System.Environment
import qualified Data.ByteString as B
import Data.ByteString.Lazy.Char8 (ByteString, singleton, splitWith)
import qualified Data.ByteString.Lazy as LB
-- Extract DNA sequence from fasta file
xtractDNA :: [ByteString] -> Maybe ByteString
xtractDNA dna = Just (LB.concat dna)
--xtractDNA = foldr ((<>) . Just) Nothing
-- Reverse Complement DNA
compStrand :: Maybe ByteString -> Maybe ByteString
compStrand = foldr ((<>) . compPairs) Nothing
where
compPairs nt | nt == (singleton 'A') = Just (singleton 'T')
| nt == (singleton 'T') = Just (singleton 'A')
| nt == (singleton 'G') = Just (singleton 'C')
| nt == (singleton 'C') = Just (singleton 'G')
| otherwise = Nothing
main :: IO ()
main = do
putStrLn "Welcome to volcano"
let fname = "/home/trinix/Development/hs_devel/local_data/shbg.fasta"
fid <- LB.readFile fname
let dna = LB.concat $ tail (LB.splitWith (==10) fid)
--putStrLn $ show (LB.length (head dna))
let dsDna = compStrand (Just dna)
print dsDna
当我执行时,我得到 Nothing
作为答案。部分输入为
"AATTCTCCATGTGCTTGGATCGTGGGGAAGATGTGATTAAGGTCTAAGGTATGTCTTCCACCAGACAACGGACACAGTCAATTAGAAGCTGGGTAAAGGGGTCTCTCCTGCGGAGCGGGGAGCGCCAAGCCAGGGACAATAATGGCCTGAAGTTCATTCTCCCGGAGATGGGGGTAGAAGCAGGTGCAGGTGCCTTAGAGGGGTCAAAAATAAGAGGAACAGGGTTCACTCTAAGCGGTCTCCCAGGGAAGGCTGCGGGTTGGAGCAAGGGTCCAAGATTCTAAGGGCCAGGACTCAGCTCCAGAAGCTCGATCCCGCCCCACGCGTTCCTGCTCCGGCCAGGGGAGGGGGCTAAGGACCGGCGTCCCCAGTCGGCGCGCCGTCTCACCTTGTAGAAGGCCCCGTTGGAGCCGCGCACCTCGACGGGCAGTCCCGGCTCCACATCCCCCCCAGAGGCCAGGCCGCCCATGGCGCCGCCACCGCCTCCGACTCCCCCGGCGGCGGCTGCAGCAGCAGTCTGAGTGCGGGCCGGGCCAGGCCCCCGGCGTCTCCCCGGAGGAGGAGCCGGAGGGGGAGCCGCGGGGGGCGGGAGCCGGGCCGGCCCCACGGCGGCCCTGCCACAGCCAACGAGCAGGGGGCCGGGGCCGGGCCGCTCCCCGTCCGCCGCCGCCGCCTTGGTCTCCGCC...ACAAGGTCAGAGGCTGGATGTGGACCAGGCCCTGAACAGAAGCCATGAGATCTGGACTCACAGCTGCCCCCAGAGCCCAGGCAATGGCACTGACGCTTCCCATTAAAGCTCCACCTAAGAACCCCC"
我怀疑我的模式匹配守卫有问题。我怎样才能弄清楚并解决这个问题?任何见解将不胜感激。
compStrand
是一个很奇怪的函数。当你只传递一个 Just 时,为什么它使用 Maybe ByteString 而不是实际的 ByteString?为什么它会做这种古怪的 foldr ((<>) . compPairs) Nothing
事情,这只是 (>>= compPairs)
的一个非常难以阅读的重新实现?
main
不是很清楚:如果您的输入是 GATC 字符串,为什么要在第一个字节等于 10 时拆分?为什么它不使用您为其编写的 xtractDNA
函数?
解决这些问题将使函数更简单,您可以更轻松地自行调试。但我会注意到,你的 compStrand
函数似乎只对单例字符串起作用,但你似乎向它传递了一个大小未知的字符串。
您正在使用 foldr
作为 Foldable
和 Maybe
,而不是 ByteString
。因此它将检查 Maybe a
。如果它是 Just
它将调用 comPairs
与 整个 ByteString
DNA,否则它将 return Nothing
.
你的 comPairs
将 return Nothing
用于任何 ByteString
是空的或有两个或更多字节,因此它 returns Nothing
.
您可以使用 mapM :: Monad m => (a -> m b) -> [a] -> m [b]
构建 Maybe [Word8]
,然后将其转换回 ByteString
:
import Data.ByteString.Lazy.Char8 (ByteString, pack, unpack)
compStrand :: Maybe ByteString -> Maybe ByteString
compStrand = (>>= fmap pack . mapM comPairs . unpack)
where comPairs 'A' = Just 'T'
comPairs 'C' = Just 'G'
comPairs 'G' = Just 'C'
comPairs 'T' = Just 'A'
comPairs _ = Nothing