haskell - 如何在 Protolude 中访问文本分解功能
问题描述
TL;博士:
在标准前奏中,可以使用String
诸如等功能head
对文本进行操作take
。Protolude
用更好的组件替换这些组件,但这似乎是以失去将许多前奏的功能应用于其标准的能力为代价的文本类型。
一个简单的问题
我需要找出某个单词是否以大写字符开头。
热身
import Data.Char
startsWithUppercase :: String -> Bool
startsWithUppercase = isUpper . head
这行得通...
λ startsWithUppercase "Yes"
True
λ startsWithUppercase "no"
False
除了那head
是一个偏函数
λ startsWithUppercase ""
*** Exception: Prelude.head: empty list
更安全的版本
import Data.Char
import Data.Maybe
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
startsWithUppercase :: String -> Bool
startsWithUppercase = (maybe False isUpper) . safeHead
这似乎可以解决问题:
λ map startsWithUppercase $ words "Yes no"
[True,False]
λ startsWithUppercase ""
False
除了我想使用Text
而不是String
从 移动String
到Text
让我们尝试直接翻译:
{-# LANGUAGE OverloadedStrings #-}
import Prelude hiding (head)
import Data.Text
import Data.Char
import Data.Maybe
safeHead :: Text -> Maybe Char
safeHead "" = Nothing
safeHead t = Just . head $ t
startsWithUppercase :: Text -> Bool
startsWithUppercase = (maybe False isUpper) . safeHead
它似乎工作......
yes, no, crash :: Text
yes = "Yes"
no = "no"
crash = ""
λ Prelude.map startsWithUppercase [yes, no, crash]
[True,False,False]
...但我不禁想知道为什么 Hoogle 没有提出任何有趣的回应Text -> Maybe Char
。
无论如何,我厌倦了到处都是这些部分功能:我不希望我的静态保证中有这些巨大的漏洞。我知道,让我们使用这些现代 Prelude 替代品之一。Protolude
看起来不错,而且似乎有很多支持者。
移动到 Protolude
Protolude,在它的众多优点中,应该解决我上面提到的两个主要问题:
- 根除
String
,Text
默认可用。 - 消除部分功能,默认提供安全的功能。
它甚至为我进口Data.Maybe
。
听起来很棒。我们开始做吧!
无需编写safeHead
,因为 inProtolude
head
已经是安全的,并且可以通用:
λ :t head
head :: Foldable f => f a -> Maybe a
出色的!
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
import Protolude
import Data.Char
startsWithUppercase :: Text -> Bool
startsWithUppercase = (maybe False isUpper) . head
哦亲爱的:
Lib.hs 8 23 error [-Wdeferred-type-errors]
• Couldn't match type ‘Text’ with ‘f0 Char’
Expected type: Text -> Bool
Actual type: f0 Char -> Bool
• In the expression: (maybe False isUpper) . head
In an equation for ‘startsWithUppercase’:
startsWithUppercase = (maybe False isUpper) . head (intero)
Protolude.head
Foldable
是在s上定义的,但Text
不是。
我想我最终还是得自己safeHead
写Text
。
嗯,但为此我使用Text.head
并Protolude
隐藏了它。
在无数次尝试让这个工作失败之后,我不得不退后一步思考:我正在尝试找出Text
一段现代前奏曲中的第一个字符是否是大写的。
我错过了什么?这个简单问题的合理解决方案是什么?更一般地说,一个人如何分解成内部Text
的子文本? Protolude
编辑:澄清
我想从中获得的好处Protolude
包括
- 减少样板进口
- 减少样板依赖规范
Protolude
有text
作为一个依赖,它进口Text
组件。
我正在寻找一种实现 whis 的方法,而无需显式指定导入和依赖项,而Protolude
.
具体来说,导出的 , 等是head
在和上定义的,不能与 一起使用。任何从显式(不受欢迎的样板编号 1)导入任何内容的尝试都会失败,因为它是“隐藏包的成员”。要解决这个问题,必须明确指定为依赖项(不受欢迎的样板编号 2)。take
any
Protolude
[]
Foldable
Text
Data.Text
text
text
有没有办法让它在没有显式导入和/或依赖项的情况下工作?
解决方案
怎么样any isUpper . take 1
(使用 和 的适当Data.Text
变体any
)take
?
推荐阅读
- javascript - 选项卡处于活动状态时未触发 Ajax Get 方法
- xamarin.forms - Xamarin 形式:RowDefinition 高度 OnIdiom 属性的正确格式是什么?
- python - Python multiprocessing Pool 'raise ValueError("Pool not running") ValueError: Pool not running' 函数返回值
- php - Laravel 审计表中的用户类型和用户 ID 为 NULL
- git - 在 Git/GitHub 中使用“模板化”项目的良好做法
- c - C - 我无法打开或读取由不同项目生成的文件
- ada - Ada:循环导致后面的代码无法访问
- kubernetes - 带有证书管理器和 Nginx 入口的 404 质询响应
- sql-server - 将数据从表中的一个单元格复制然后插入到该表中的另一个单元格
- javascript - ajax post API URL不适用于表单onClick按钮