我对Haskell和功能编程很新...
我希望将函数作为字符串传递,并计算使用haskell的函数中存在的每个语法,例如(if,else,elseif for,while,dowhile)。
例如,如果给出这样的输入
if(i=0){ for(i=0;i<num;i++){if(name== name)}
}elseif (i=3){for(i=3;i<num;i++){}}
else{while (i>3){name = name; i--;}}
我期待输出。(它必须不给出每种语法出现的次数)
[(if,2),(for,2),(elseif,1),(else,1),(while,1)]
我完成了编码。如下图所示
import Control.Arrow
syntaxCount :: String -> [(String, Int)]
syntaxCount = map (head &&& length) . group .sort . words
此功能有效,但会显示如下结果。
[("(i=3){for(i=3;i<num;i++){}}",1),("(i>3){name",1),("=",1),("else{while",1),("for(i=0;i<num;i++){if(name==",1),("i--;}}",1),("if(i=0){",1),("name)}",1),("name;",1),("}elseif",1)]
任何人都可以帮助我摆脱所有不需要的东西并得到像这样的结果..
[(if,2),(for,12),(elseif,1),(else,1),(while,1)]
答案 0 :(得分:4)
我将其拆分为一个函数,该函数生成输入字符串中的关键字列表,以及计算列表中不同元素的函数
import Data.Char
import Control.Arrow
keywords :: String -> [String]
keywords = words . map (\x -> if isAlpha x then x else ' ')
count :: Ord k => [k] -> [(k,Int)]
count = map (head &&& length) . group . sort
然后,您可以将syntaxCount
定义为简单的合成
syntaxCount = count . keywords
例如
>> let inp = "if(i=0){ for(i=0;i<num;i++){if(name== name)}\n}elseif (i=3){for(i=3;i<num;i++){}}\nelse{while (i>3){name = name; i--;}}"
>> syntaxCount inp
[("else",1),("elseif",1),("for",2),("i",10),("if",2),("name",4),("num",2),("while",1)]
如果您只想包含一组特定的关键字,那么您应该明确过滤这些关键字
import qualified Data.Set as Set
allKeywords :: Set.Set String
allKeywords = Set.fromList ["if", "else", "elseif", "for", "while"]
keywords = filter (`Set.member` allKeywords) . words . map removePunc
where removePunc c = if isAlpha c then c else ' '