HLintでよく指摘される内容
今作成しているライブラリでHLint
を実行してみました。傾向としては、冗長なdo
と冗長なカッコの指摘が多いようでした。
src/Database\SQLServer\Internal\Tokens.hs:626:1: Suggestion: Use newtype instead of data Found: data ROW = ROW{columnValues :: [ColumnValue]} deriving (Show, Eq, Generic) Why not: newtype ROW = ROW{columnValues :: [ColumnValue]} deriving (Show, Eq, Generic) Note: decreases laziness
src/Database\SQLServer\Internal\Types.hs:406:20: Warning: Use replicate Found: take n $ repeat $ Bit.block Bit.bool Why not: replicate n (Bit.block Bit.bool)
src/Database\SQLServer\ResultSet.hs:467:37: Suggestion: Avoid lambda Found: \ row -> getRecord' meta row Why not: getRecord' meta
src/Lib.hs:71:20: Suggestion: Use null Found: length x == 0 Why not: null x Note: increases laziness
src/Lib.hs:90:12: Suggestion: Move brackets to avoid $ Found: "[trace] [c] ====================> RCPRequest request " ++ (show $ BS.length rcpreq) Why not: "[trace] [c] ====================> RCPRequest request " ++ show (BS.length rcpreq)
src/Lib.hs:127:3: Warning: Use maybe Found: if isJust rawsql then example_execute_sql_raw socket $ fromJust rawsql else maybe (case rpc of Just (r, _) -> example_execute_rpc socket r Nothing -> error "invalid parameter") (example_execute_sql socket) file Why not: maybe (maybe (case rpc of Just (r, _) -> example_execute_rpc socket r Nothing -> error "invalid parameter") (example_execute_sql socket) file) (example_execute_sql_raw socket) rawsql
src/Lib.hs:142:16: Suggestion: Redundant $ Found: runGet (MT.evalStateT resolveTokens []) $ batchRes Why not: runGet (MT.evalStateT resolveTokens []) batchRes
src/Lib.hs:143:3: Warning: Use when Found: if info then mapM_ (printToken) tokens else return () Why not: Control.Monad.when info $ mapM_ (printToken) tokens
src/Lib.hs:150:15: Warning: Redundant do Found: do mapM_ (mapM_ putStrLn) $ getRecordList2Str rs Why not: mapM_ (mapM_ putStrLn) $ getRecordList2Str rs
rc/Lib.hs:226:13: Suggestion: Use <$> Found: MT.lift (get :: Get RETURNSTATUS) >>= return . TknreturnStatus Why not: TknreturnStatus <$> MT.lift (get :: Get RETURNSTATUS)
src/Lib.hs:410:4: Suggestion: Redundant bracket Found: "@foo" @@ (fromGregorian 1900 1 1) Why not: "@foo" @@ fromGregorian 1900 1
.\src\Lib.hs:483:54: Suggestion: Use section Found: ((==) '=') Why not: ('=' ==)
.\src\Lib.hs:516:1: Suggestion: Use camelCase Found: exNullSql_variant = ... Why not: exNullSqlVariant = ...
io-streamでストリームを変更する
Generator
を作る必要があります。
以下のようにしてしまうと、固定値を永遠に流すストリームになってしまいます。
badFunc :: InputStream Int -> IO (InputStream Int) badFunc s = do v <- S.read s case v of Just x -> makeInputStream $ return $ Just x Nothing -> makeInputStream $ return Nothin
ファイルに行番号をつける
io-stream
でinputstream
を作りつなげるだけ。
is-streamでファイルコピー(デバック付き)
デバック部分はコメントアウトしています。
CoqからHaskellのコードを生成する
Extraction
という機能を使うとできるらしい。Coq
で証明してHaskell
で動作させる感じなのか。
単純な方の定義
Inductive FBB : Type := | Foo | Bar | Buzz. Require Extraction. Extraction Language Haskell. Extraction "C:\work\FBB.hs" FBB.
module FBB where import qualified Prelude data FBB = Foo | Bar | Buzz
偶数判定は以下のように変換される。
Fixpoint evenb (n:nat) : bool := match n with | O => true | S O => false | S (S n') => evenb n' end.
module Evneb where import qualified Prelude data Bool = True | False data Nat = O | S Nat evenb :: Nat -> Bool evenb n = case n of { O -> True; S n0 -> case n0 of { O -> False; S n' -> evenb n'}}