有没有办法在Haskell中取消映射?

Maa*_*sen 3 haskell

我正在写一个Haskell程序.我创建了一个名为measurement的数据类型,它是一个双精度数组,它看起来像这样:

data Measurement = Measurement [Double]  deriving (Show)
Run Code Online (Sandbox Code Playgroud)

我有一个强制转换为Measurement的功能,它需要一个双打列表列表,并将其转换为测量列表.它看起来像这样:

castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement
Run Code Online (Sandbox Code Playgroud)

但现在我想对双值进行一些操作.那么有没有一种方法可以取消映射到双打数组?因此,当我给它一个Measurement(或测量列表)时,它会将它转换为双打列表(或双列表列表).谢谢!

Aad*_*hah 6

就在这里:

data Measurement = Measurement { getMeasurement :: [Double] } deriving Show

castToMeasurement :: [[Double]] -> [Measurement]
castToMeasurement = map Measurement

castFromMeasurement :: [Measurement] -> [[Double]]
castFromMeasurement = map getMeasurement
Run Code Online (Sandbox Code Playgroud)

简单,不是吗?

  • @MaartenMeeusen你应该阅读有关记录语法:[here](https://www.haskell.org/haskellwiki/Constructor)或[here](http://learnyouahaskell.com/making-our-own-types-and-类型类) (5认同)

Lui*_*las 6

好吧,不,是的.

你说出这个问题的方式,是否有一种"取消映射"的方法,答案必须是否定的,而不是一般的.假设我们有一个字符串列表:

example1 :: [String]
example1 = ["Hello", "cruel", "world"]
Run Code Online (Sandbox Code Playgroud)

我们可以用它map length来映射字符串的长度:

example2 :: [Int]
example2 = map length example
-- value: [5, 5, 5]
Run Code Online (Sandbox Code Playgroud)

但是没有办法"取消映射"价值example2以取回原件example1.那将需要一个函数,在给定长度的情况下,找出原始列表中的哪个字符串 - 但这显然是信息不足!

但是这给了我们一个关于我们可以执行你想要的"取消映射"的情况的提示.如果我们最初映射的函数具有,那么我们可以用该逆映射到"撤消"效果map.在您的情况下,Measurement构造函数确实有一个逆:

-- | The inverse of the 'Measurement' constructor.  Laws:
--
-- > Measurement (getMeasurement x) == x
-- > getMeasurement (Measurement xs) == xs
getMeasurement :: Measurement -> [Double]
getMeasurement (Measurement xs) = xs
Run Code Online (Sandbox Code Playgroud)

由于MeasurementgetMeasurement是逆它遵循map Measurementmap getMeasurement是为好,所以:

map getMeasurement (map Measurement xs) == xs
map Measurement (map getMeasurement xs) == xs
Run Code Online (Sandbox Code Playgroud)