Functional programming 我应该如何绘制可能的列表?
我带着一种似乎是对也许的误解离开了 我相信:Functional programming 我应该如何绘制可能的列表?,functional-programming,monads,elm,maybe,sanctuary,Functional Programming,Monads,Elm,Maybe,Sanctuary,我带着一种似乎是对也许的误解离开了 我相信: map(add1, Just [1, 2, 3]) // => Just [2, 3, 4] 从前面的指南中,我的感觉是,Maybe.map应该尝试调用数组上的Array.map,基本上返回Just(map(add1[1,2,3]) 当我尝试使用的Maybe类型和最近的Maybe类型时,我失望地发现他们都不支持这个(或者,也许,我不明白他们是如何支持这个的) 在庇护所 > S.map(S.add(1), S.Just([1, 2, 3]
map(add1, Just [1, 2, 3])
// => Just [2, 3, 4]
从前面的指南中,我的感觉是,Maybe.map
应该尝试调用数组上的Array.map
,基本上返回Just(map(add1[1,2,3])
当我尝试使用的Maybe类型和最近的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]])
应该返回[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 S.compose(S.map,S.map)(S.add(1))(S.Just([1,2,3]))
只是([2,3,4])
类似地,我觉得我应该能够将Just(Just(1))
视为Just(1)
这可以使用elm社区/maybe extra
包中的来完成
join(Just(Just 1))==Just 1
join(只是Nothing)=Nothing
无连接==无连接
避难所也有一个功能,因此您可以执行以下操作:
> Maybe.map (List.map (add 1)) (Just [1, 2, 3])
Just [2,3,4] : Maybe.Maybe (List number)
S.join(S.Just(S.Just(1))==Just(1)
S.join(S.Just(S.Nothing))==无
S.join(S.Nothing)=Nothing
如Chad所述,您希望转换嵌套在两个函子中的值
让我们先逐个映射每个,以获得舒适感:
> 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
的函数必须是数组(数字)->数组(数字)
S.map(S.add(1))类型的函数就是这样一种功能。将这一切结合在一起,我们可以得出:
> S.map(S.map(S.add(1)), S.Just([1, 2, 3]))
Just([2, 3, 4])
在Haskell中,有一个为定义的函子实例,因此,
fmap
在合成函子内部工作两个层次。在导入数据.Functor.Compose
之后,getCompose$fmap(1+)$Compose$Just[1,2,3]
返回Just[2,3,4]
Compose
/getCompose
只是类型系统的助手。Haskell什么都有,嗯!嘿!你就是那个人!:)上帝保佑stackoverflow。几个月后,我明白了!函数add1
是number->number
,map将add1提升到Maybe number->Maybe number
。我试图将一个函数应用于Maybe number
类型的值。这不起作用!在您的上一次示例中你可以先将add1
提升为F number->F number
,然后将其提升为Maybe F number->Maybe F number
,最后将其应用于Maybe F number
类型的值。我可以使用s.map(s.add(1))真是太酷了
创建一个函数F number->F number
,然后将该函数同时应用于S.Just(1)
和[1,2,3]
,即使它们有不同的类型!一个是可能是number
和列表number
。多态性的魔力!