2014-06-09 14 views
5

Così oggi ho chiesto circa implementing inits via foldr. Ho una domanda simile per le code ora. Per prima cosa: ho una soluzione. Tuttavia non è la soluzione di cui ho bisogno, ma la soluzione che merito. O qualcosa del genere:Implementare le code utilizzando foldr in Haskell

Codice:

tails :: [a] -> [[a]] 
tails = foldr (\ x y -> reverse([] : reverse(map (x:) y))) [[]] 

Questo fornisce risultati corretti, ma non soddisfa il modello del nostro prof impostato per noi. Il modello si presenta così:

tails :: [a] -> [[a]] 
tails = foldr (\ x y -> undefined : undefined) undefined 

Così, ovviamente, la mia funzione ha bisogno di modifiche, ma non ho ricevuto la mia testa intorno ad esso, dal momento che ho sempre ricadere la mia soluzione.

Qualche consiglio su come risolvere questo problema?

Grazie in anticipo.

risolto:

tails :: [a] -> [[a]] 
tails = foldr (\ x y -> (x : (head y)) : y) [[]] 
+1

Suggerimento: con il modello del tuo professore, ad ogni passo, 'y' deve essere uguale a 'tails xs' dove' xs' è la parte dell'elenco originale a destra di 'x', e' indefinito: undefined' deve essere qualcosa che usa 'x' e' y' per costruire il diritto valore per 'tails (x: xs)'. –

risposta

4

Alcuni indizi:

  • Voi sapete che tails [] == [[]], in modo che il valore iniziale deve essere [[]], quindi dovrete

    tails = foldr (\x y -> undefined : undefined) [[]]

  • length (tails xs !! n) > length (tails xs !! (n+1)) o in inglese semplice: la lunghezza di ciascuna coda si accorcia man mano che si scende nell'elenco.

  • Cosa ne pensi di foldr (\x (y:ys) -> undefined : undefined) [[]]?

Se rimani bloccato dopo un po 'di nuovo (o hanno già pensato di questi), lasciare un commento e io ti do un'altra gomitata.

+0

Il valore dell'accumulatore non è un problema. Il mio problema è che devo aggiungere un elemento nella parte anteriore dell'elenco (ovvero x o [], poiché y non è il tipo corretto). Questo mi butta via in qualche modo. Va bene per l'iterazione più interna (il valore più a destra della lista data e l'accumulata), ma oltre a ciò sono solo lucidato – powlomat

+1

@powlomat Questo è principalmente il mio ultimo suggerimento. Se si esegue lo schema di corrispondenza sull'accumulatore ('y') come' y: ys', allora 'y :: [a]', 'x :: a' e' ys :: [[a]] '. Cosa puoi fare con tutto ciò? – bheklilr

+0

Sì, mi piacerebbe farlo, ma il risultato è un pattern match non accettato (nello strumento di correzione che usiamo) :(Mi è stato permesso di sostituire i termini "indefiniti", non diversamente:/ – powlomat

3

Sidenote, interessa a me che la comunità Haskell su questo sito in genere non mi piace dare risposte piatte, quindi credo che seguirò la tendenza (anche il PO non ha chiesto una risposta a tutto gas)

Ecco alcuni suggerimenti:

  • foldr pieghe da destra a sinistra

  • sguardo all'uscita del tails "abc", è ["abc", "bc", "c", ""]. Come costruisci la lista andando da destra a sinistra? (o in altre parole, anteporre le cose all'elenco)

  • Qual è la differenza tra gli elementi del risultato, guardando da destra a sinistra? C'è uno schema?

+2

Penso che sia perché se una domanda si presenta come compito a casa, gli indizi si traducono in più apprendimenti per lo studente di qualcosa che puoi copiare e compilare. – AndrewC

0

Non so perché, ma mi sembra di vedere dipana ovunque negli ultimi tempi, anche in questa domanda:

import Data.List (unfoldr) 
import Data.Maybe (listToMaybe) 

tails :: [a] -> [[a]] 
tails = unfoldr (\ xs -> listToMaybe xs >> Just (xs, tail xs)) 
+0

Sembra un uso terribilmente scomodo di 'listToMaybe'. Che ne dici di' tails = unfoldr (\ xs - > do {(_: tl) <- restituisce xs; return (xs, tl)}) 'invece? – dfeuer

+0

Forse meglio: Definisci' uncons [] = Nothing', 'uncons (x: xs) = Just (x, xs) '(questo potrebbe essere in una libreria da qualche parte, ma lo trovo solo per' Text' e 'ByteS tring' e cose). Quindi usa 'tails = unfoldr (\ xs -> uncons xs >> = \ (_, tl) -> Just (xs, tl))' – dfeuer

+1

C'è un problema serio: 'tails' non è uno spiegamento; non c'è proprio modo di ottenere la coda vuota. Vogliamo 'unfold f [] = [[]]' che significa che 'f [] = Just ([], qualcosa)', ma allora 'f something' deve essere' Nothing', e non c'è una lista reale che possa essere usato per 'qualcosa'! – dfeuer

Problemi correlati