gpt4 book ai didi

haskell - 如何在 Haskell 中为 Foldable 编写 tailMay,而不使用不安全的函数?

转载 作者:行者123 更新时间:2023-12-02 20:36:58 26 4
gpt4 key购买 nike

签名应该是:

tailMay :: Foldable f => f a -> Maybe (f a)

我得到了 headMay 的定义,这是有道理的,并且(对我来说)相当聪明:

headMay :: Foldable f => f a -> Maybe a
headMay = foldr (const . Just) Nothing

不幸的是,我无法想到 tailMay 类似的东西。 ,和similar implementations似乎使用了魔法或不安全的函数。

如果这是不可能的,那么可以使用 (Applicative t, Foldable t) 的方法也适合我的目的(我认为这也意味着 Traversable t )。

最佳答案

Tail 仅对类似列表的结构有意义,因此返回列表而不是相同的容器类型 f 是明智的。实现很简单,可以通过多种方式完成,这里是一种。

import Control.Monad (guard)
import Data.Foldable (toList)

tailMay :: Foldable f => f a -> Maybe [a]
tailMay xs = guard (not (null xs)) >> Just (drop 1 (toList xs))

但是,由于它适用于所有类似列表的结构,因此我们可以很酷地为所有具有 IsList 的事物定义它。

{-# LANGUAGE TypeFamilies #-}
import Control.Monad (guard)
import Data.Foldable (toList)
import GHC.Exts (IsList(Item, fromList))

tailMay :: (IsList l, Item l ~ a, Foldable f) => f a -> Maybe l
tailMay xs = guard (not (null xs)) >> Just (fromList (drop 1 (toList xs)))

编辑

上述解决方案的一个好处是您可以将类型从参数更改为结果。例如,您可以从 Vector 开始,然后使用 Set 结果。但这也有一个缺点,您需要自己指定结果类型:

因此运行此命令将导致编译错误:

λ> tailMay [1 :: Int]
<interactive>:24:1-18: error:
• Illegal equational constraint Item l ~ Int
(Use GADTs or TypeFamilies to permit this)
• When checking the inferred type
it :: forall l. (IsList l, Item l ~ Int) => Maybe l
λ> tailMay [1 :: Int] :: Maybe [Int]
Just []

如果上述确实是一个问题或者对我们来说只是一个不希望的效果,我们可以轻松限制结果类型:

tailMay :: (IsList l, Item l ~ a, Foldable f, l ~ f a) => f a -> Maybe l

之后效果很好:

λ> import qualified Data.Vector as V
λ> tailMay $ V.enumFromTo 'a' 'd'
Just "bcd"
λ> tailMay [1 :: Int]
Just []
λ> tailMay V.empty
Nothing
λ> tailMay []
Nothing

警告 - 一切都会很棒,但不幸的是,不能保证 fromList 将有一个完整的实现:

λ> import qualified Data.List.NonEmpty as NE
λ> tailMay (5 NE.:| [] :: NE.NonEmpty Int)
Just *** Exception: NonEmpty.fromList: empty list

除了创建您自己的 IsList 之类的类并为所有此类数据结构提供您自己的实例之外,没有通用的方法可以保护您自己免受其影响。

关于haskell - 如何在 Haskell 中为 Foldable 编写 tailMay,而不使用不安全的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58977458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com