Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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
Haskell 为什么不是';这不是打字很好吗?_Haskell - Fatal编程技术网

Haskell 为什么不是';这不是打字很好吗?

Haskell 为什么不是';这不是打字很好吗?,haskell,Haskell,我正在编写一个函数来生成一组字符串的所有排列--“foo”应该返回{“foo”,“ofo”,“oof”}。我已经在Clojure中这样做了,所以我知道这种方法是正确的,但我想我应该在Haskell中进行实践。下面是我得到的 import qualified Data.Set as Set substr :: String -> Int -> Int -> String substr s start end = take (end - start) . drop start $

我正在编写一个函数来生成一组字符串的所有排列--“foo”应该返回{“foo”,“ofo”,“oof”}。我已经在Clojure中这样做了,所以我知道这种方法是正确的,但我想我应该在Haskell中进行实践。下面是我得到的

import qualified Data.Set as Set

substr :: String -> Int -> Int -> String
substr s start end = take (end - start) . drop start $ s

substrs :: String -> Set.Set (Char, String)
substrs s = let len = length s
            in foldl (\acc x -> Set.insert (s !! x, ((substr s 0 x)++(substr s (succ x) len))) acc) Set.empty [0..len-1]

-- not sure about the type
permute [] = Set.empty
permute s = Set.map recurFunc (substrs s)
  where recurFunc (c, s) = Set.map (c:) (permute s)

main :: IO ()
main = print $ permute "foo!"
当然,这不是编译,否则我不会问。我得到:

permute.hs:12:21:
Couldn't match expected type `String'
            with actual type `Set.Set [Char]'
Expected type: (Char, String) -> String
  Actual type: (Char, String) -> Set.Set [Char]
In the first argument of `Set.map', namely `recurFunc'
In the expression: Set.map recurFunc (substrs s)

Set.map
声明为
(a->b)->Set a->Set b
。据我所知,
recurFunc
获取一组
(Char,String)
对,并返回一组字符串
substrs
返回一组
(字符、字符串)
对。那么这是怎么不一致的呢?

请注意:
键入String=[Char]

Set.map
采用普通函数并将其映射到集合上。由于您有一个
集(Char,String)
并且您想要一个
集字符串
,因此此函数的类型应为
(Char,String)->String

但是,
recurFunc
返回的是一个集合,而不仅仅是一个字符串。也就是说,它有一个类型
(Char,String)->Set String
。(我认为类型实际上更一般,但这并不重要。)因此,当你将它映射到一个集合上时,你会得到一组集合:类似于
set(set String)

这是您的错误以稍微有点偏颇的方式说的:它期望一个
Set字符串
,但得到了一个
Set(Set字符串)
。但是,由于错误是关于
recurFunc
,因此它只告诉您函数的问题:
Set String
应该是
String


希望这能为您提供足够的信息来修复错误。

利用
String
s只是
Char
s的列表这一事实,您可以快速编写:

import Data.List

permute = Eq a => [a] -> [[a]]
permute = nub . permutations
预定义的
permutations
实际上生成了您想要的所有作业,而
nub
只是删除重复项


请注意,这种方法不是非常有效(O(n^2)),应该只用于少量数据

我建议首先使用基于列表的版本,然后调整它,以便在以后如果您决定确实需要它时使用
Set
。列表不那么容易混淆(而且,对于像这样的少量数据,
Set
也不会快很多)。