Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何实现“反”的功能;插入;(将字符串拆分为字符上的片段)使用来自;“基”是什么;?_String_List_Haskell_Split - Fatal编程技术网

String 如何实现“反”的功能;插入;(将字符串拆分为字符上的片段)使用来自;“基”是什么;?

String 如何实现“反”的功能;插入;(将字符串拆分为字符上的片段)使用来自;“基”是什么;?,string,list,haskell,split,String,List,Haskell,Split,我想在换行符上拆分一个字符串,我很惊讶我找不到要拆分的反函数。也就是说,一个将字符串拆分为新行(或根据其他谓词)上的片段的函数 请注意,行和字做了一些不同的事情。比如说 intercalate "\n" (lines "a\n") == "a" 拆分库中有一个类似的函数。我也可以自己直接编写这样一个函数: splitOn :: (a -> Bool) -> [a] -> [[a]] splitOn p = map reverse . g [] where g rs

我想在换行符上拆分一个字符串,我很惊讶我找不到要拆分的反函数。也就是说,一个将字符串拆分为新行(或根据其他谓词)上的片段的函数

请注意,
做了一些不同的事情。比如说

intercalate "\n" (lines "a\n") == "a"
拆分库中有一个类似的函数。我也可以自己直接编写这样一个函数:

splitOn :: (a -> Bool) -> [a] -> [[a]]
splitOn p = map reverse . g []
  where
    g rs []                 = [rs]
    g rs (x:xs) | p x       = rs : g [] xs
                | otherwise = g (x : rs) xs

但是我想知道,如果只使用来自的函数,是否可以更容易地构造它。

如果您正在寻找更原始的函数的组合,那么除了基于
unfover
break
的方法,我想不出其他方法,但是
unfover
不在
前奏曲中


无论如何,我想你很清楚,
Prelude
远远不是我们很多人想要的,所以它甚至不能解决这样一个看似微不足道的问题也就不足为奇了。《序曲》
的一般问题似乎是它的曲解不当:该模块旨在提供足以与Haskell一起玩的东西作为介绍的一部分,正如其名称所示,但由于没有标准的“基本”模块,Haskeller倾向于将其视为一个。

正如Nikita Volkov指出的,限制“仅前奏曲功能”并不容易,但这里有一个选项:

splitWhen p [] = [[]]
splitWhen p l  = uncurry (:) . fmap (splitWhen p . drop 1) . break p $ l
这使用了
(,)a
函子
实例作为
控件.Arrow.second
(以避免使用messier lambda表达式)的替代方法,该方法无需导入任何内容(ghci表示“在'GHC.Base'中定义”),但我不确定这是否真的属于
序言
,因为我在Haskell报告中找不到它

编辑:允许使用
base
中的其他函数对我没有多大帮助。无论如何,我会使用
second
而不是
fmap
,因为我认为这会增加一点清晰度。使用
展开器
,使用
可能
作为种子来区分字符串的结尾和空白y部分(或示例中的空行):

import-Control.Applicative(())
导入控制。箭头(第二个)
导入数据列表(展开器)
当p=展开器时拆分(第二次检查。断开p)。只需
哪里
检查[]=无
检查(u:rest)=只需休息
--或者用“Data.Maybe.listToMaybe”把它塞进一行
拆分时间'p=

展开器(第二个(\rest->tail rest)这与Data.List.Split中的
splitOn
不同。这一个具有类型签名
[a]->[a]->[[a]]
,而您的类型签名相当于
a->[a]->[[a]]
。区别在于在子字符串上拆分或在单个字符上拆分。但是我们有来自
parsercompbinators
sebby
,这个
splitOn
类似于
Data.List.Split.splitWhen
。你必须使用
字符串类型吗?文本和
ByteString.Char8
都有
spl它
用于分解字符串的函数。@LukeTaylor很遗憾,是的。我想参与的库没有使用任何函数,我觉得只为这个函数添加依赖项不是很好。对不起,我把问题说错了。我的意图是只使用“base”中的函数,而不需要额外的库包,而不仅仅是Prelude模块。对不起,我把问题说错了。我的意图是只使用“base”中的函数,而不需要额外的库包,而不仅仅是Prelude模块。
import Control.Applicative ((<$>))
import Control.Arrow (second)
import Data.List (unfoldr)

splitWhen p = unfoldr (second check . break p <$>) . Just
  where
    check []       = Nothing
    check (_:rest) = Just rest

-- or cramming it into a single line with 'Data.Maybe.listToMaybe'
splitWhen' p =
  unfoldr (second (\rest -> tail rest <$ listToMaybe rest) . break p <$>) . Just