Ani*_*tla 10 syntax binary haskell
我正在查看Cloud Haskell软件包的Encoding.hs,并遇到了一些奇怪的代码,我希望有人可以帮助我更好地理解.包括必要的代码:
class (Binary a,Typeable a) => Serializable a
instance (Binary a,Typeable a) => Serializable a
data Payload = Payload
{
payloadType :: !ByteString,
payloadContent :: !ByteString
} deriving (Typeable)
serialDecodePure :: (Serializable a) => Payload -> Maybe a
serialDecodePure a = (\id ->
let pc = payloadContent a
in pc `seq`
if (decode $! payloadType a) == show (typeOf $ id undefined)
then Just (id $! decode pc)
else Nothing ) id
Run Code Online (Sandbox Code Playgroud)
我只是好奇什么是$!(我猜测只是严格评估),还有为什么我们需要id技巧(懒惰评估的东西?).另外我特意遇到这条线的问题:
if (decode $! payloadType a) == show (typeOf $ id undefined)
Run Code Online (Sandbox Code Playgroud)
我猜这是因为无论出于何种原因,看看payloadType是否无效,但如果是这种情况,则不应切换then和else子句,即更改:
if (decode $! payloadType a) == show (typeOf $ id undefined)
then Just (id $! decode pc)
else Nothing
Run Code Online (Sandbox Code Playgroud)
至
if (decode $! payloadType a) == show (typeOf $ id undefined)
then Nothing
else Just (id $! decode pc)
Run Code Online (Sandbox Code Playgroud)
感谢您的任何帮助,您可以提供.
Joh*_*n L 12
你是对的,$!
是一个严格的评估者.它的类型是相同的$
,唯一的语义差异是第二个参数seq
在传递给函数之前是'd'.
我认为id
实际上有帮助类型推断.在功能块中(\id -> ...)
,该函数id
被强制为具有类型a -> a
,其中a
不仅是任何类型变量,而是与a
in 相同
serialDecodePure :: (Serializable a) => Payload -> Maybe a
Run Code Online (Sandbox Code Playgroud)
这是由于这一行:
Just (id $! decode pc)
Run Code Online (Sandbox Code Playgroud)
由于这有类型Maybe a
,id
有推断类型a -> a
.结果,在你正在看的线上,
if (decode $! payloadType a) == show (typeOf $ id undefined)
Run Code Online (Sandbox Code Playgroud)
id undefined :: a
,哪里a
再与输出相同.
现在我们可以进行类型检查.由于此函数是多态的并且将解码为任何类型,因此需要检查编码数据是否与其解码的类型兼容.如果您编码String
并尝试解码Int
为什么怎么办?LHS将解码为"[Char]",这是String的TypeRep表示.RHS将改为"Int",它正在尝试解码的类型.由于它们不相等,所以"else"路径是返回的路径None
.
而不是这个id函数类型限制,你可以用ScopedTypeVariables
扩展完成相同的事情.