将字符串连接到一个列表中

时间:2014-11-26 12:32:55

标签: haskell concatenation ghci

我想要做的是我想将一个字符串列表作为输入并执行一些操作然后返回一个字符串列表。问题是,我正在为每种情况寻找特定但通用的字符串模式:

func :: [String] -> [String]
func [] = []
func [x] = [x]
func (["Not","(","Not"]:es:[")"]) = es  --HERE
func ("Not":"(":pred:"And":rest:")") = ("Not":pred:"Or":(pushNotInwards rest))
func ("Not":"(":pred:"Or":rest:")") = ("Not":pred:"And":(pushNotInwards rest))
func ("Not":"(":"ForAll":x:scope:")") = ("Exists":"Not":"("scope:")")
func ("Not":"(":"Exists":x:scope:")") = ("ForAll":"Not":"(":scope:")")

例如,对于第三种情况,我想以以下形式获取字符串列表:

  

[ “不”, “(”, “不”,some_strings, “)”]

我尝试在左侧使用++作为:

func (["Not"]++["("]++["Not"])++es++[")"]) = es

我还尝试了concat:,但它们也没有用。有什么建议吗?

2 个答案:

答案 0 :(得分:3)

你似乎对不同的字符串运算符有些困惑。

String只是字符列表的同义词,即[Char]。冒号:运算符(又名cons)将一个元素添加到列表的开头。这是它的类型:

*Main> :t (:)
(:) :: a -> [a] -> [a]

例如:

*Main> 1:[2,3]
[1,2,3]
*Main> 'a':"bc"
"abc"

++运算符连接两个列表。这是它的类型:

*Main> :t (++)
(++) :: [a] -> [a] -> [a]

模式匹配只能使用数据构造函数完成。 :运算符是数据构造函数,但++运算符不是。因此,您无法使用++运算符上的模式匹配来定义函数。

要使用模式匹配来定义函数,我建议为不同的函数和限定符定义新的数据类型,而不是使用字符串:

-- Logic Operation
data LogicOp =
    Not LogicOp | And [LogicOp] | Or [LogicOp] |
    Forall String LogicOp | Exists String LogicOp | T | F
  deriving (Eq, Show)

func :: LogicOp -> LogicOp
func (Not (Not x)) = x
func (Not (And (pred:rest))) = Or (Not pred:[func (Not (And rest))])
func (Not (Or  (pred:rest))) = And (Not pred:[func (Not (Or rest))])
func (Not (Forall x scope)) = Exists x (Not scope)
func (Not (Exists x scope)) = Forall x (Not scope)
func x = x

以下是一些例子:

*Main> func (Not (Not T))
T
*Main> func (Not (And [T, F, T]))
Or [Not T,Or [Not F,Or [Not T,Not (And [])]]]
*Main> func (Not (Or [T, F, T]))
And [Not T,And [Not F,And [Not T,Not (Or [])]]]
*Main> func (Not (Forall "x" (And T F))
*Main> func (Not (Forall "x" (And [T, F])))
Exists "x" (Not (And [T,F]))
*Main> func (Not (Exists "x" (And [T, F])))
Forall "x" (Not (And [T,F]))

答案 1 :(得分:2)

你可能不应该使用字符串。创建一个新类型:

 data SomeExpr = Not SomeExpr
               | And SomeExpr SomeExpr
               | Or  SomeExpr SomeExpr
               deriving (Show)

然后你可以匹配那个表达式:

 func :: SomeExpr -> SomeExpr
 func (Not (Not x)) = func x
 func (Not (And x y)) = Or (Not $ func x) (Not $ func y)
 func (Not (Or  x y)) = And (Not $ func x) (Not $ func y)
 ...
 func x = x

您无法对中间的列表进行模式匹配,例如,您希望[1,2,3,4,5](1:middle:5:[])匹配,但这无效。

是的,使用自己的类型有它自己的问题,你必须解析它等,但它比字符串(可能有任意内容)更容易和更安全。