我该如何内联此功能?

时间:2012-06-20 18:02:44

标签: haskell parsec

我有两个函数,但其​​中一个函数只从另一个调用,所以我想内联辅助函数。我的代码如下所示:

data PoS =  N | V | Adj | Adv | Phr

posEntity :: Parser PoS
posEntity = 
    do pos <- string "N." <|>
              string "V." <|>
              string "Adj." <|>
              string "Adv." <|>
              string "Phr."
       return (posToPoS pos)
    <?> "part of speech"

posToPoS pos
    | pos == "N." = N
    | pos == "V." = V
    | pos == "Adj." = Adj
    | pos == "Adv." = Adv
    | pos == "Phr." = Phr

显然应该内联posToPoS,但我不确定做这样的事情所需的语法。

谢谢!

4 个答案:

答案 0 :(得分:8)

您可以将定义中的字符串内联到posToPos

posToPoS "N." = N
posToPoS "V." = V
-- ... etc

或者,您可以直接在解析器中使用以下方法:

import Control.Applicative hiding (<|>)

posEntity :: Parser PoS
posEntity = 
  (string "N."   *> pure N   <|>
   string "V."   *> pure V   <|>
   string "Adj." *> pure Adj <|>
   string "Adv." *> pure Adv <|>
   string "Phr." *> pure Phr)<?> "part of speech"

(您可能需要string "foo" *> pure Foo部分周围的问题,我忘记了运算符的优先级)

答案 1 :(得分:4)

GHC可能会在优化时自动内联。但是,要强制它这样做,只需在代码中的某处添加{-# INLINE posToPoS #-},最好在posToPoS的定义旁边。

为了使它成为本地的,只有posEntity可以看到它,你需要一个where子句。如此定义:

data PoS =  N | V | Adj | Adv | Phr

posEntity :: Parser PoS
posEntity = 
    do pos <- string "N." <|>
              string "V." <|>
              string "Adj." <|>
              string "Adv." <|>
              string "Phr."
       return (posToPoS pos)
    <?> "part of speech" where
        posToPoS pos
            | pos == "N." = N
            | pos == "V." = V
            | pos == "Adj." = Adj
            | pos == "Adv." = Adv
            | pos == "Phr." = Phr

答案 2 :(得分:1)

在您的示例中,简单的case语句似乎是更好的解决方案:

posEntity = 
    do pos <- string "N." <|>
              string "V." <|>
              string "Adj." <|>
              string "Adv." <|>
              string "Phr."
       return $ case pos of
                  "N." -> N
                  "V." -> V
                  "Adj." -> Adj
                  "Adv." -> Adv
                  "Phr." -> Phr
    <?> "part of speech"

如果你有选择的话,模式匹配通常比平等比较更受欢迎。

答案 3 :(得分:0)

这是我想出来的。对不起,如果我不清楚:

posEntity :: Parser PoS
posEntity = 
    do pos <- string "N." <|>
              string "V." <|>
              string "Adj." <|>
              string "Adv." <|>
              string "Phr."
       return (posToPoS pos)
    <?> "part of speech"
    where
      posToPoS pos
          | pos == "N." = N
          | pos == "V." = V
          | pos == "Adj." = Adj
          | pos == "Adv." = Adv
          | pos == "Phr." = Phr