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 作为 FoldableMaybe,而不是 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