Wer*_*ria 1 haskell coding-style
我是Haskell的新手,我想要一些关于改进这个脚本的意见.这是一个代码生成器,需要一个命令行参数来生成sql脚本.
./GenCode "people name:string age:integer"
Run Code Online (Sandbox Code Playgroud)
码:
import Data.List
import System.Environment (getArgs)
create_table :: String -> String
create_table str = "CREATE TABLE " ++ h (words str)
where h (x:xs) = let cab = x
final = xs
in x ++ "( " ++ create_fields xs ++ ")"
create_fields (x:xs) = takeWhile (/=':') x ++ type x ++ sig
where sig | length xs > 0 = "," ++ create_fields xs
| otherwise = " " ++ create_fields xs
create_fields [] = ""
type x | isInfixOf "string" x = " CHARACTER VARYING"
| isInfixOf "integer" x = " INTEGER"
| isInfixOf "date" x = " DATE"
| isInfixOf "serial" x = " SERIAL"
| otherwise = ""
main = mainWith
where mainWith = do
args <- getArgs
case args of
[] -> putStrLn $ "You need one argument"
(x:xs) -> putStrLn $ (create_table x)
Run Code Online (Sandbox Code Playgroud)
我想你已经了解了如何编写功能代码.这是一些小风格的笔记:
create_table,cabo并且final不被使用.Data.List.intercalate "," (map create_field xs).然后create_field x就可以了takeWhile (/=':') x ++ type x像这样:
types = Data.Map.fromList [("string", "CHARACTER VARYING")
,("integer", "INTEGER")
-- etc
]
Run Code Online (Sandbox Code Playgroud)
然后type就可以了Data.Maybe.fromMaybe "" (Data.Map.lookup x types)
main.(这是个人喜好)说啊
main = do
args <- getArgs
case args of
[] -> ...
Run Code Online (Sandbox Code Playgroud)
putStrLn.在第一次调用中,参数不需要括号,在第二次调用中,您提供括号.或者,您可以保留第二个美元并放下括号.不要使用length xs > 0(in sig); 它毫无疑问地计算了xs你真正想知道的时间长度是否为空.使用null xs来检查非空列表:
...
where sig | null xs = ... -- Empty case
| otherwise = ... -- Non-empty case
Run Code Online (Sandbox Code Playgroud)
或添加参数sig和模式匹配:
...
where sig (y:ys) = ...
sig [] = ...
Run Code Online (Sandbox Code Playgroud)
虽然内森桑德斯建议用intercalate一个很好的替代整个递归的东西,但这是一个有争议的问题.
您还要通过传递整个"var:type"字符串来识别类型type,因此它正在测试
"string" `isInfixOf` "name:string"
Run Code Online (Sandbox Code Playgroud)
等等
您可以使用break或span代替takeWhile以前分隔名称和类型:
create_fields (x:xs) = xname ++ type xtype ++ sig
where
(xname, _:xtype) = break (==':') x
sig = ...
Run Code Online (Sandbox Code Playgroud)
然后type可以比较字符串相等,或使用a查找值Map.
快速解释使用break:
break (==':') "name:string" == ("name", ":string")
Run Code Online (Sandbox Code Playgroud)
然后绑定时
(xname, _:xtype) to ("name", ":string"),
xname -> "name"
_ -> ':' (discarded)
xtype -> "string"
Run Code Online (Sandbox Code Playgroud)