微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 Purescript 中的元组中取出一个可能

如何解决从 Purescript 中的元组中取出一个可能

我有一个看起来像这样的函数

import Data.Bifunctor (lmap)
import Data.Int (fromString)

keyToInt :: forall a. Tuple String a -> Tuple (Maybe Int) a
keyToInt = lmap fromString 

我想要的是这种类型签名:

keyToInt :: forall a. Tuple String a -> Maybe (Tuple Int a)

这似乎有效:

keyToInt :: forall a. Tuple String a -> Maybe (Tuple Int a)
keyToInt tuple = extractFstMaybe $ lmap fromString tuple
  where
    extractFstMaybe :: forall a. Tuple (Maybe Int) a -> Maybe (Tuple Int a)
    extractFstMaybe (Tuple (Just a) b) = Just $ Tuple a b
    extractFstMaybe (Tuple nothing _) = nothing

但感觉应该有一种更抽象/更清晰的方式来表达这一点。如果我将 extractMaybe 归为自然结论,我可能会创建类似

-- The typing doesn't really work for this
extractMaybe :: forall a b c d. (Tuple a b) -> Maybe (Tuple c d)
extractMaybe (Tuple (Just a) (Just b)) = Just $ Tuple a b
extractMaybe (Tuple (Just a) b) = Just $ Tuple a b
extractMaybe (Tuple a (Just b)) = Just $ Tuple a b
extractMaybe (Tuple nothing _) = nothing
extractMaybe (Tuple _ nothing) = nothing
extractMaybe (Tuple a b) = Just $ Tuple a b

在阅读有关 applicatives 和 bind 的内容时,这是我经常看到的那种重构。我还没有真正为自己应用这些课程的经验。

如果我有一个可能包含 ADT(EitherMaybeArray 的数组)的结构,并且我想定义一种方法来拉动这些”出,”有没有一种通用的方法来定义它?


Purescript by Example一个函数类型签名的例子:

combineList :: forall f a. applicative f => List (f a) -> f (List a)

这是在做同样的事情,只针对一个列表。 N-Tuples 使这变得复杂,因为每个元素都可以有不同的类型。如果我在元组调用 extractMaybe,我现在有一个包含任何类型的元组除了对于 Maybe(或者我有 nothing)。

我可以为 Either 编写相同的内容,如果我同时使用两者,我可以知道我有一个包含任何类型的元组 除了 Maybe 和 {{1} }(或者我有Either)。

我什至不完全确定这是最有用的方向。在 nothing 这样的情况下,您想过滤掉所有 mapMaybenothing 似乎很有帮助s 同时解开这些类型。

解决方法

这正是ltraverse

module Main where

import Data.Bitraversable (ltraverse)
import Data.Int (fromString)
import Data.Tuple (Tuple)
import Data.Maybe (Maybe)

keyToInt :: forall a. Tuple String a -> Maybe (Tuple Int a)
keyToInt = ltraverse fromString 

每当您解构一个类型并将其构造回另一个类型(例如 Maybe)时,这就是您想要 traverse 的时候。在这种情况下,Tuple 有两个你可以遍历的东西,使它成为 Bitraversable。对于此函数,您希望遍历 Tuple 的左侧 - 即 ltraverse

,

我可能会这样编程:

keyToInt (Tuple a b) = ado
  a' <- fromString a
  in Tuple a' b

因为它接近许多类似的需求。您可以轻松地对 b 应用某些内容,或对除 Tuple 以外的内容进行模式匹配,或将结果与除 Tuple 以外的内容相结合。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。