我应该如何映射 Maybe List?
How should I map over Maybe List?
我离开 Professor Frisby's Mostly Adequate Guide to Functional Programming 时似乎对 Maybe 有误解。
我相信:
map(add1, Just [1, 2, 3])
// => Just [2, 3, 4]
我对上述指南的看法是,Maybe.map
应该尝试在数组上调用 Array.map
,本质上是 returning Just(map(add1, [1, 2, 3])
.
当我尝试使用 Sanctuary's Maybe type, and more recently Elm 的 Maybe 类型时,我很失望地发现他们都不支持这个(或者,也许我不明白他们是如何支持这个的)。
在避难所,
> S.map(S.add(1), S.Just([1, 2, 3]))
! Invalid value
add :: FiniteNumber -> FiniteNumber -> FiniteNumber
^^^^^^^^^^^^
1
1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber
The value at position 1 is not a member of ‘FiniteNumber’.
在榆树中,
> Maybe.map sqrt (Just [1, 2, 3])
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The 2nd argument to function `map` is causing a mismatch.
4| Maybe.map sqrt (Just [1, 2, 3])
^^^^^^^^^^^^^^
Function `map` is expecting the 2nd argument to be:
Maybe Float
But it is:
Maybe (List number)
同样,我觉得我应该能够将 Just(Just(1))
视为 Just(1)
。另一方面,我对 [[1]]
的直觉完全相反。显然,map(add1, [[1]])
应该 return [NaN]
而不是 [[2]]
或任何其他东西。
在 Elm 中,我能够执行以下操作:
> Maybe.map (List.map (add 1)) (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
这是我想做的,但不是我想做的。
如何映射到 Maybe 列表?
您有两个仿函数需要处理:Maybe
和 List
。您正在寻找的是将它们组合起来的某种方法。您可以通过函数组合简化您发布的 Elm 示例:
> (Maybe.map << List.map) add1 (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
这实际上只是您发布的示例的简写,您说的不是如何您想做的。
避难所有一个compose
函数,所以上面的表示为:
> S.compose(S.map, S.map)(S.add(1))(S.Just([1, 2, 3]))
Just([2, 3, 4])
Similarly, I feel like I should be able to treat a Just(Just(1))
as a Just(1)
这可以使用 elm-community/maybe-extra
包中的 join
来完成。
join (Just (Just 1)) == Just 1
join (Just Nothing) == Nothing
join Nothing == Nothing
避难所也有join
功能,所以您可以进行以下操作:
S.join(S.Just(S.Just(1))) == Just(1)
S.join(S.Just(S.Nothing)) == Nothing
S.join(S.Nothing) == Nothing
正如乍得提到的,您想要转换嵌套在 两个 仿函数中的值。
让我们开始对每个单独进行映射以便舒服:
> S.map(S.toUpper, ['foo', 'bar', 'baz'])
['FOO', 'BAR', 'BAZ']
> S.map(Math.sqrt, S.Just(64))
Just(8)
让我们考虑一下地图的一般类型:
map :: Functor f => (a -> b) -> f a -> f b
现在,让我们将此类型专门用于上述两种用途:
map :: (String -> String) -> Array String -> Array String
map :: (Number -> Number) -> Maybe Number -> Maybe Number
到目前为止一切顺利。但在您的情况下,我们希望映射 Maybe (Array Number)
类型的值。我们需要一个这种类型的函数:
:: Maybe (Array Number) -> Maybe (Array Number)
如果我们映射 S.Just([1, 2, 3])
,我们需要提供一个以 [1, 2, 3]
(内在值)作为参数的函数。所以我们提供给S.map
的函数一定是Array (Number) -> Array (Number)
类型的函数。 S.map(S.add(1))
就是这样一个函数。综上所述,我们得出:
> S.map(S.map(S.add(1)), S.Just([1, 2, 3]))
Just([2, 3, 4])
我离开 Professor Frisby's Mostly Adequate Guide to Functional Programming 时似乎对 Maybe 有误解。
我相信:
map(add1, Just [1, 2, 3])
// => Just [2, 3, 4]
我对上述指南的看法是,Maybe.map
应该尝试在数组上调用 Array.map
,本质上是 returning Just(map(add1, [1, 2, 3])
.
当我尝试使用 Sanctuary's Maybe type, and more recently Elm 的 Maybe 类型时,我很失望地发现他们都不支持这个(或者,也许我不明白他们是如何支持这个的)。
在避难所,
> S.map(S.add(1), S.Just([1, 2, 3]))
! Invalid value
add :: FiniteNumber -> FiniteNumber -> FiniteNumber
^^^^^^^^^^^^
1
1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber
The value at position 1 is not a member of ‘FiniteNumber’.
在榆树中,
> Maybe.map sqrt (Just [1, 2, 3])
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The 2nd argument to function `map` is causing a mismatch.
4| Maybe.map sqrt (Just [1, 2, 3])
^^^^^^^^^^^^^^
Function `map` is expecting the 2nd argument to be:
Maybe Float
But it is:
Maybe (List number)
同样,我觉得我应该能够将 Just(Just(1))
视为 Just(1)
。另一方面,我对 [[1]]
的直觉完全相反。显然,map(add1, [[1]])
应该 return [NaN]
而不是 [[2]]
或任何其他东西。
在 Elm 中,我能够执行以下操作:
> Maybe.map (List.map (add 1)) (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
这是我想做的,但不是我想做的。
如何映射到 Maybe 列表?
您有两个仿函数需要处理:Maybe
和 List
。您正在寻找的是将它们组合起来的某种方法。您可以通过函数组合简化您发布的 Elm 示例:
> (Maybe.map << List.map) add1 (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
这实际上只是您发布的示例的简写,您说的不是如何您想做的。
避难所有一个compose
函数,所以上面的表示为:
> S.compose(S.map, S.map)(S.add(1))(S.Just([1, 2, 3]))
Just([2, 3, 4])
Similarly, I feel like I should be able to treat a
Just(Just(1))
as aJust(1)
这可以使用 elm-community/maybe-extra
包中的 join
来完成。
join (Just (Just 1)) == Just 1
join (Just Nothing) == Nothing
join Nothing == Nothing
避难所也有join
功能,所以您可以进行以下操作:
S.join(S.Just(S.Just(1))) == Just(1)
S.join(S.Just(S.Nothing)) == Nothing
S.join(S.Nothing) == Nothing
正如乍得提到的,您想要转换嵌套在 两个 仿函数中的值。
让我们开始对每个单独进行映射以便舒服:
> S.map(S.toUpper, ['foo', 'bar', 'baz'])
['FOO', 'BAR', 'BAZ']
> S.map(Math.sqrt, S.Just(64))
Just(8)
让我们考虑一下地图的一般类型:
map :: Functor f => (a -> b) -> f a -> f b
现在,让我们将此类型专门用于上述两种用途:
map :: (String -> String) -> Array String -> Array String
map :: (Number -> Number) -> Maybe Number -> Maybe Number
到目前为止一切顺利。但在您的情况下,我们希望映射 Maybe (Array Number)
类型的值。我们需要一个这种类型的函数:
:: Maybe (Array Number) -> Maybe (Array Number)
如果我们映射 S.Just([1, 2, 3])
,我们需要提供一个以 [1, 2, 3]
(内在值)作为参数的函数。所以我们提供给S.map
的函数一定是Array (Number) -> Array (Number)
类型的函数。 S.map(S.add(1))
就是这样一个函数。综上所述,我们得出:
> S.map(S.map(S.add(1)), S.Just([1, 2, 3]))
Just([2, 3, 4])