简体   繁体   中英

Haskell type system explanation?

I cant get my call to the function to compile. All the commented calls are failed attempts. Please advise, also is there any good explanation of Haskels type system out there??

import Data.Numbers.Primes
import Data.List

--isInt:: Fractional a => a -> Bool
isInt x =
   x == fromInteger (round x)


doForm :: (Integral int, Fractional int) => int -> int -> Bool
doForm cube n =
         isPrime (divide - n)  
   where divide =   cube / (n^2) 



main =
   -- print $ doForm (12^3 8)
   -- print $ doForm (12^3::Integer 8::Integer ) 
   -- print $ doForm ( fromIntegral 12^3 fromIntegral 8)
   -- print $ doForm (toInteger 12^3 toInteger 8)
   -- print $ doForm (toInteger 12^3 toInteger (8) )
   -- print $doForm (round 12^3)  ( round 8)
   -- print $doForm (floor 12^3)  ( floor 8)
   -- print $doForm ( 12^3::Fractional  8::Fractional)
   -- print $doForm ( 12^3 8)::Fractional
   -- print $doForm (12^3 :: RealFrac 8::RealFrac )

There are no types in the Prelude which are instances of both Integral and Fractional , so you will need to pick one or the other constraint and stick with it. You can convert with functions like these ones:

fromIntegral :: (Integral a, Num b) => a -> b -- Num is a superclass of Fractional
floor, ceiling, round :: (RealFrac a, Integral b) => a -> b -- Fractional is a superclass of RealFrac

You may also want to carefully consider whether you want (/) or div for division.

(/) :: Fractional a => a -> a -> a
div :: Integral   a => a -> a -> a

Integral and Fractional not only aren't overlapping in the standard library, but form a contradiction in terms. Integral(2) states the number has no fractional part (coming after a decimal point), while fractional(1) states it may. This is one sort of property described by the type classes.

In the case of a Fractional type, you can check if the fractional part is zero using something like:

isInt :: RealFrac a => a -> Bool
isInt n = snd (properFraction n) == 0

RealFrac states that the number is both fractional and real . Complex numbers support division but don't have a single definition for fractional part.

Considering you want to check if a number is prime, and only positive integers can be prime, we could choose to reduce the test to only handling integral types:

doForm :: Integral int => int -> int -> Bool
doForm cube n = case remainder of
             0 -> isPrime (quotient - n)
             _ -> False
   where (quotient,remainder) = cube `quotRem` (n^2)

main =
    print $ doForm (12^3) 8

A number being positive or non-negative is another property one might have expressed in a type system (for instance, Ada has ranged integers ), but Haskell's prelude does not. Haskell report section 6.3, standard Haskell Classes lists the type classes in standard Haskell. Other packages might extend this, for instance nat provides positive and non-negative integers and NonEmpty provides non-empty lists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM