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
。多态性的魔力!