-1
votes

Existe-t-il un moyen d'obtenir une fonction «Split» à Haskell pour accepter deux types d'entrées différents?

J'essaie de créer une fente de fonction pouvant prendre [int] et int ou strand> [Char] Char pour diviser soit une liste d'entiers sur un entier donné ou diviser une chaîne sur un caractère étant donné. I.e.

class Split a where
  split :: (Eq a) => [a] -> a -> [a]

instance Split [Char] Char where
  split [] c     = [""]
  split (x:xs) c
    | x == c    = "" : (split xs c)
    | otherwise = (x : head (split xs c)) : tail (split xs c)

instance Split [Int] Int where
  split [] n = []
  split (x:xs) n
    | x == n = [] : (split xs n)
    | otherwise = (x : head (split xs n)) : tail (split xs n)


3 commentaires

N'utilisez pas de cours, écrivez simplement une fonction polymorphe avec le bon type par exemple. Split :: (EQ A) => [A] -> A -> [[[A]] .


Peut-être que vous voulez faire un scission de classe f avec Split :: EQ A => FA -> A -> FA , vous pouvez définir une division d'instance [ ] .


Les cours étaient définitivement dans la mauvaise façon de résoudre ce problème - je viens d'inclure ma tentative d'essayer de démontrer ce que j'essayais de faire


4 Réponses :


4
votes

Vous avez besoin d'une fonction polymorphe divisée xxx

implémentation est simple xxx

edit < / strong> Je suggère une implémentation différente. xxx


2 commentaires

L'axe est une faute de frappe de sous-remplacement


Exactement ce que je cherchais - merci beaucoup



2
votes

Juste pour contribuer avec une autre approche. Cette solution utilise replier code>. Je pense que c'est assez propre mais moins incessible que @ Talex's

split :: (Eq a) => [a] -> a -> [[a]]
split l c = foldr f acc l
   where acc = [[]]
         f a t@(i@(x:_):xs) = if a == c then []:t else (a:i):xs -- Case when the current accumulator is not empty
--                                           |          |- cons a to current accumulator
--                                           |- start a new accumulator
         f a t@([]:xs)      = if a == c then t    else [a]:xs -- Case when the current accumulator is empty. Usefull when two separators are together
--                                           |          |- cons a to current accumulator
--                                           |- Don't start a new accumulator, just continue with the current


0 commentaires

1
votes

juste une solution correcte.

split :: Eq a => [a] -> a -> [[a]]                                          
split xs delim = go $ dropWhile (== delim) xs                               
  where                                                                     
    go [] = []                                                              
    go xs = let (tok, rest) = break (== delim) xs                           
             in tok : go (dropWhile (== delim) rest)


0 commentaires

1
votes

data.list.split.spliton code> (disponible à partir du package code> Split (code>) est proche: xxx pré>

Votre Split :: EQ A => [A] -> A -> [[[[[A]] code> serait P>

split lst d = filter (not.null) $ splitOn [d] lst


0 commentaires