我想比较数据类型的构造函数“tag”。
有一种简单的方法吗?
5
答案 0 :(得分:4)
您可能希望将构造函数与通配符进行模式匹配。像这样:
...
var initVectorBytes = Encoding.UTF8.GetBytes(initVector);
var saltValueBytes = Encoding.UTF8.GetBytes(saltValue);
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
string cipherText;
using (var memoryStream = new MemoryStream())
{
using (var password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations))
{
var keyBytes = password.GetBytes(keySize/8);
using (var symmetricKey = new RijndaelManaged {Mode = CipherMode.CBC})
{
var encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);
var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var cipherTextBytes = memoryStream.ToArray();
cipherText = Convert.ToBase64String(cipherTextBytes);
}
}
}
return cipherText;
...
答案 1 :(得分:2)
有几种方法可以做到这一点,没有一种方法是完美的。
您可以通过比较数据种类类型代表来执行类似操作:
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeApplications #-}
import Data.Typeable
data D = A | B Int | C Char
kCheck :: Typeable a => Proxy (a::k) -> D -> Bool
kCheck p d = typeRep p == kTypeRep where
kTypeRep = case d of
A -> typeRep (Proxy @ 'A)
B {} -> typeRep (Proxy @ 'B)
C {} -> typeRep (Proxy @ 'C)
(如果你没有ghc 8.0.1删除TypeApplications
并将@ 'A
替换为:: Proxy 'A
)我认为这需要ghc 7.10(或者可能是7.8 {{1} }})。
AutoDeriveTypeable
或者您可以使用kCheck (Proxy @ 'B) (B 3)
True
kCheck (Proxy @ 'C) A
False
并比较TemplateHaskell
s:
Name
如果您对比较字符串感到满意,可以使用{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
data D = A | B Int | C Char
thCheck :: Name -> D -> Bool
thCheck n d = n == conName
where
conName = case d of
A -> 'A
B {} -> 'B
C {} -> 'C
> thCheck 'B (B 3)
True
> thCheck 'A (C 'a')
False
中的toConstr
自动导出字符串:
Data
有一种最接近你想要的方法但这只有在每个类型构造函数具有不同类型时才有效。 因此{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
data D = A | B Int | C Int
deriving Data
dCheck :: String -> D -> Bool
dCheck s d = s == show (toConstr d)
和data D = A Int | B Int
的类型代表都是A
,所以这不会与B
一起使用。
Int -> D
按预期工作:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data D = A | B Int | C String
deriving Typeable
check :: Typeable a => a -> D -> Bool
check p d = typeOf p == conTypeRep
where
conTypeRep = case d of
A -> typeOf A
B {} -> typeOf B
C {} -> typeOf C