web-dev-qa-db-fra.com

Division à Haskell

Je crée une fonction dans Haskell qui réduit de moitié uniquement les éléments d'une liste et je rencontre un problème. Lorsque je lance le compliant, il se plaint que vous ne pouvez pas effectuer la division d'un int et que j'ai besoin d'une déclaration de type int fractionnaire. J'ai essayé de changer la déclaration de type en float, mais cela a juste généré une autre erreur. J'ai inclus le code de la fonction ci-dessous et j'espérais pour toute forme d'aide.

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x/2:halfEvens xs

Merci pour la lecture.

26
D347th

Utilisez div , qui effectue une division entière:

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x `div` 2 : halfEvens xs

Le (/) La fonction requiert des arguments dont le type est dans la classe Fractional et effectue une division standard. La fonction div nécessite des arguments dont le type est dans la classe Integral et effectue une division entière.

Plus précisément, div et mod arrondissent vers l'infini négatif. Leurs cousins, quot et rem, se comportent comme division entière en C et arrondissent vers zéro. div et mod sont généralement corrects lorsque vous effectuez une arithmétique modulaire (par exemple lors du calcul du jour de la semaine en fonction d'une date), tandis que quot et rem sont légèrement plus rapide (je pense).

Jouer un peu dans GHCi:

> :t div
div :: Integral a => a -> a -> a
> :t (/)
(/) :: Fractional a => a -> a -> a
> 3 / 5
0.6
> 3 `div` 5
0
> (-3) `div` 5
-1
> (-3) `quot` 5
0
> [x `mod` 3 | x <- [-10..10]]
[2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1]
> [x `rem` 3 | x <- [-10..10]]
[-1,0,-2,-1,0,-2,-1,0,-2,-1,0,1,2,0,1,2,0,1,2,0,1]
39
Joey Adams

Je dois ajouter que l'utilisation de map simplifierait le code.

HalfIfEven n
  | even n = n `div` 2
  | otherwise = n

halfEvens = map halfIfEven
0
Caridorc