通常,当我使用Haskell编写内容时,我需要具有多个构造函数的记录.例如,我想开发某种逻辑方案建模.我想到了这样的类型:
data Block a = Binary {
binOp :: a -> a -> a
, opName :: String
, in1 :: String
, in2 :: String
, out :: String
} | Unary {
unOp :: a -> a
, opName :: String
, in_ :: String
, out :: String
}
Run Code Online (Sandbox Code Playgroud)
它描述了两种类型的块:二进制(如和,或等)和一元(如不是).它们包含核心功能,输入和输出信号.
另一个例子:类型来描述控制台命令.
data Command = Command { info :: CommandInfo
, action :: Args -> Action () }
| FileCommand { info :: CommandInfo
, fileAction :: F.File …Run Code Online (Sandbox Code Playgroud) 我实现了读取ByteString并以十六进制格式转换它的函数.例如,给定"AA10",它将其转换为[170,16]
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString.Internal as BS (w2c)
rHex :: BSL.ByteString -> BSL.ByteString
rHex bs
| BSL.null bs = BSL.empty
| BSL.null rest' = fromHex c1 `BSL.cons` BSL.empty
| otherwise = rChunk c1 c2 `BSL.cons` rHex rest
where (c1, rest') = (BSL.head bs, BSL.tail bs)
(c2, rest) = (BSL.head rest', BSL.tail rest')
rChunk c1 c2 = (fromHex c1) * 16 + fromHex c2
fromHex = fromIntegral . digitToInt . BS.w2c
Run Code Online (Sandbox Code Playgroud)
但是我意识到我需要相同的功能但是对于简单的ByteString,而不是Lazy.我遇到的唯一方法是这样的:
import qualified Data.ByteString.Lazy as BSL …Run Code Online (Sandbox Code Playgroud) 写这样的东西是可以的:
head $ foldr (:) [] [1..]
-- 1
Run Code Online (Sandbox Code Playgroud)
但是当我尝试处理元组时,它会进入无限循环:
head . fst $ foldr (\ x (ls, _) -> (x : ls, 0)) ([], 0) [1..]
Run Code Online (Sandbox Code Playgroud)
我需要这个的原因是因为我想在内部函数中传递生成元素的计数.像那样:
foldr go ([], 0) [1..]
go num (ls, cnt) = -- use cnt to get l and produce new pair (l : ls, cnt + 1)
Run Code Online (Sandbox Code Playgroud)