3

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

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

4 回答 4

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,我忘记了运算符的优先级是什么)

于 2012-06-20T18:09:39.123 回答
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
于 2012-06-20T18:05:30.877 回答
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"

如果可以选择,模式匹配通常比相等比较更可取。

于 2012-06-20T18:10:27.660 回答
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
于 2012-06-20T18:09:24.197 回答