je pars d'une liste de liste : l1=[[1,2,3],[4,5,6],[7,8,9]] :: Int
et je voudrais faire la somme des 2 diagonales. Par exemple dans ce cas là : 1+5+9 grâce à une fonction sommeDiag1 et faire 3+5+7 avec sommeDiag2.
Je ne vois pas bien comment faire.
Si quelqu'un a une idée.
Voici ce que j'ai commencé :
sommeDiag1 :: Int -> Int
sommeDiag1 [] = 0
sommeDiag1 (x:xs) = let i = 1
in (head x)!!i + sommeDiag1 xs
Merci
# Indice
Posté par LoupSolitaire . Évalué à 1.
[^] # Re: Indice
Posté par Johands . Évalué à 2.
Le hic, c'est que j'ai encore du mal à imaginer une université enseignant l'Haskell en France (ou dans les pays francophones), vu la faible notoriété du langage et l'héritage du Caml.
# Chouette du Haskell !
Posté par Johands . Évalué à 2.
[^] # Re: Chouette du Haskell !
Posté par LoupSolitaire . Évalué à 2.
[^] # Re: Chouette du Haskell !
Posté par eoutin . Évalué à 1.
Au revoir.
[^] # Re: Chouette du Haskell !
Posté par NeoX . Évalué à 8.
# Laid
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3.
Donc tu parcoures tes listes, avec un compteur d'indice incrémenté à chaque nouvelle liste. Et tu additionnes "les éléments à l'indice i de chaque liste l_i".
Pour diag2, c'est la même chose, sauf que tu inverses l'ordre de tes listes pour les parcourir à l'envers…
l1=[[1,2,3],[4,5,6],[7,8,9]]
diag1 = fst . foldl (\(x,c) y -> (x+(y!!c),c+1)) (0,0)
diag2 = diag1 . reverse
main = do
print $ diag1 l1
print $ diag2 l1
[^] # Autre petit problème
Posté par eoutin . Évalué à 1.
j'ai un nouveau soucis, cette fois c'est une histoire de IO.
j'ai une fonction shuffle qui mélange une liste donnée (de type [a]) et qui renvoie cette liste mélangée alétoirement (de type IO [a]).
Cependant, je veux utiliser cette fonction shuffle dans une autre fonction (qui ne prend pas de IO [a] en argument mais [a]).
Je voudrais donc en quelque sorte convertir xs :: IO [Integer] en xs :: [Integer] pour ne pas avoir de soucis dans la fonction qui utilise shuffle.
Voici ma fonction shuffle :
shuffle' [] acc = return acc
shuffle' l acc =
do k <- randomRIO (0, length l - 1)
let (lead, x:xs) = splitAt k l
shuffle' (lead ++ xs) (x:acc)
shuffle :: [a] -> IO [a]
shuffle l = shuffle' l []
Merci.
[^] # Re: Autre petit problème
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3.
Il faut donc que tu repenses ton problème autrement, c'est à dire que tu remarques que tu voudras éventuellement utiliser ton résultat, par exemple pour l'afficher. Et donc tu veux rester dans IO. Comme je vois juste une fonction et pas de main (dont le type est IO ()), j'en déduis que tu ne sais même pas ce que tu veux faire. Donc écrit main, et ensuite, code en te disant "je suis dans la monade IO"
Exemple simple :
import Random (randomRIO)
import System (getArgs)
shuffle' [] acc = return acc
shuffle' l acc = do
k <- randomRIO (0, length l - 1)
let (lead, x:xs) = splitAt k l
shuffle' (lead ++ xs) (x:acc)
shuffle :: [a] -> IO [a]
shuffle l = shuffle' l []
ma_fonction_normale :: [String] -> [(String, Int)]
ma_fonction_normale = map (\x -> (x, ((read x)+2)))
main = do
liste_d_entiers <- getArgs -- récupère une liste de nombres passés au programme
itlse_d_enteisr <- shuffle liste_d_entiers -- permute
let resultat = ma_fonction_normale itlse_d_enteisr -- applique une fonction "pas IO"
print resultat -- affiche le résultat et quitte
[^] # Re: Autre petit problème
Posté par Johands . Évalué à 1.
1 - comme écrit dans la réponse précédente, quand tu joues avec la monad IO, tu ne peux plus en sortir. C'est un des fondements de Haskell : une fonction utilisant des données externes (IO) est impure et doit être confinée à l'écart du code restant. Autrement formulé : il est impossible de convertir un "IO a" en "a".
2 - il est peut-être possible d'éviter la monad IO pour l'instant en préférant randomR et randomRs à randomRIO cf l'API Haskell pour plus de détails.
3 - c'est pas joli de faire des postes en doubles !!
[^] # Re: Autre petit problème
Posté par eoutin . Évalué à 1.
Pour en revenir à mon problème, j'ai bien compris que c'était bien compliqué cette histoire de monad IO.
Je vous met aussi la fonction dans laquelle je veut réutiliser ma liste mélangée aléatoirement.
data Mobile = Poids Rational | Branche Rational Mobile Mobile deriving Show
poids :: Mobile -> Rational
poids (Poids n) = n
poids (Branche _ g d) = poids g + poids d
shuffle' [] acc = return acc
shuffle' l acc =
do k <- randomRIO (0, length l - 1)
let (lead, x:xs) = splitAt k l
shuffle' (lead ++ xs) (x:acc)
shuffle :: [a] -> IO [a]
shuffle l = shuffle' l []
ranCreation :: [Rational] -> Mobile
ranCreation [] = (Poids 0)
ranCreation [p] = (Poids p)
ranCreation li = let m = splity li; x = (fst m); y = (snd m); k = (poids (ranCreation y))/(poids (ranCreation x) + poids (ranCreation y))
in ((Branche k) (ranCreation x) (ranCreation y))
splity :: [a] -> ([a],[a]) --Fonction qui découpe une liste en 2
splity x = let n = div (length x) 2
in splitAt n x
Ma fonction ranCreation me permettrai donc de créer des mobiles aléatoires, en mélangeant à chaque fois les listes de poids.
Merci à vous.
[^] # Re: Autre petit problème
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3.
Haskell, c'est un mensonge. On te dit "c'est pur, mais on peut faire des effets de bord dans la monade IO". La vérité, c'est que tu dois TOUT faire dans la monade IO. Tu dois TOUT faire à partir de la fonction main. Donc tu peux TOUJOURS extraire tes données avec l'opérateur "<-"
Désormais, tu coderas dans un fichier, avec un main, et tu feras ":!ghci %" ou l'équivalent pour emacs. Et tu lanceras "main" dans ton interprète, si ça type.
En pratique, une dernière fois (après, je moinsse !)
import Random (randomRIO)
import System (getArgs)
data Mobile = Poids Rational | Branche Rational Mobile Mobile deriving Show
poids :: Mobile -> Rational
poids (Poids n) = n
poids (Branche _ g d) = poids g + poids d
shuffle' [] acc = return acc
shuffle' l acc = do
k <- randomRIO (0, length l - 1)
let (lead, x:xs) = splitAt k l
shuffle' (lead ++ xs) (x:acc)
shuffle :: [a] -> IO [a]
shuffle l = shuffle' l []
splity :: [a] -> ([a],[a])
splity x = splitAt n x where
n = div (length x) 2
ranCreation :: [Rational] -> Mobile
ranCreation [] = (Poids 0)
ranCreation [p] = (Poids p)
ranCreation li = Branche k (ranCreation x) (ranCreation y) where
m = splity li
x = fst m
y = snd m
k = (poids (ranCreation y))/(poids (ranCreation x) + (poids (ranCreation y)))
main = do
liste <- getArgs
let liste_nombres = (map (fromIntegral . read) liste)
let arbre1 = ranCreation liste_nombres
liste_nombres_randomisee <- shuffle liste_nombres -- ICI !!!!
let arbre2 = ranCreation $ liste_nombres_randomisee -- LA !!!!
print arbre1
print arbre2
Ensuite,
ghc --make toto.hs
./toto 1 3 90
Et voilà !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.