简体   繁体   English

Haskell-函数中的单词交换

[英]Haskell - swap words in a function

I'm trying to create a function which swaps a string (w1) in a sentence with another string (w2). 我正在尝试创建一个函数,该函数将句子中的字符串(w1)与另一个字符串(w2)交换。 Here is what I have so far: 这是我到目前为止的内容:

swapwords :: String -> String -> String -> String 
swapwords w1 w2 [] = [] 
swapwords w1 w2 (x:xs) 
    | length (x:xs) < n = (x:xs) 
    | otherwise = do 
if w1 == take n (x:xs) then w2 ++ swapwords w1 w2 (drop n (x:xs)) 
else x:swapwords w1 w2 xs 
where 
    n = length w1 

However, I'm getting an 'undefined variable "main"' error, and 'Warning: Defined but not used: `w1'' and 'w2'. 但是,我收到“未定义的变量“ main””错误,并且出现“警告:已定义但未使用:w1”和“ w2”。 What am I doing wrong? 我究竟做错了什么?

The error is due to you trying to build an executable from a module that does not define a function main . 该错误是由于您试图从未定义函数main的模块中构建可执行文件而引起的。 The warnings are caused by your code being somewhat awkwardly indented (I am assuming that you are using a Haskell 98 compiler; GHC 7.8.3 accepts your code if you compile it in Haskell 2010 mode.) 警告是由于您的代码缩进有点尴尬(我假设您使用的是Haskell 98编译器;如果在Haskell 2010模式下进行编译,GHC 7.8.3会接受您的代码。)

Although you can use do -notation to construct expressions of type String (as strings are lists and the type constructor for lists is a monad), it is a bit strange to do it in this context (you are not really doing anything monadic with the string you are constructing, aren't you?). 尽管您可以使用do -notation构造String类型的表达式(因为字符串是列表,列表的类型构造函数是monad),但在这种情况下这样做有点奇怪(您实际上并没有对monadic做任何事情您正在构造的字符串,不是吗?)。

Slightly reformatting your code and adding a function main will make your code compile (also as Haskell 98) to an executable: 稍微重新格式化代码并添加函数main将使您的代码编译为可执行文件(也可作为Haskell 98):

swapwords :: String -> String -> String   -> String 
swapwords    w1        w2        []       =  [] 
swapwords    w1        w2        (x : xs)
  | length (x:xs) < n                     = x : xs  
  | otherwise                             =
      if   w1 == take n (x:xs)
      then w2 ++ swapwords w1 w2 (drop n (x:xs)) 
      else x : swapwords w1 w2 xs 
  where 
    n = length w1

main :: IO ()
main =  putStrLn (swapwords "bar" "qux" "foo bar baz")

Running this executable then allows you to test your code: 然后运行此可执行文件可以测试代码:

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.3

$ ghc -XHaskell98 Test.hs -o test.exe
[1 of 1] Compiling Main             ( Test.hs, Test.o )
Linking test.exe ...

$ ./test.exe 
foo qux baz

While this has nothing to do with your compile problems, here is another way you could implement your function using Text.Regex.PCRE : 尽管这与您的编译问题无关,但是这是使用Text.Regex.PCRE实现函数的另一种方式:

module Swap where

import Text.Regex.PCRE ((=~))

swap :: String -> String -> String -> String
swap orig toSwap ws =
  case ws =~ orig :: (String,String,String) of
   (_,"","") -> ws
   (b,_,a) -> b ++ toSwap ++ a

Although this text-icu library is probably better for this by now, as Text.Regex doesn't support Text.Data.Text 尽管到目前为止, 这个text-icu库可能对此更好,因为Text.Regex不支持Text.Data.Text

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM