Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loss of polymorphism after pattern matching

The following code is intended to produce either a Double or an Integer. s is assumed to be either negate or id; n the whole part; and f the fractional part or Nothing for an integer.

computeValue :: Num a => (a->a) -> Integer -> (Maybe Double) -> Either Double Integer
computeValue s n Nothing = Right $ s n
computeValue s n (Just a) = Left $ s (fromIntegral n + a)

when I compile this I get:

test1.hs:2:28:
    Couldn't match type `Integer' with `Double'
    Expected type: Either Double Integer
      Actual type: Either Double a
    In the expression: Right $ s n
    In an equation for `computeValue':
        computeValue s n Nothing = Right $ s n

test1.hs:2:38:
    Couldn't match type `Integer' with `Double'
    In the first argument of `s', namely `n'
    In the second argument of `($)', namely `s n'
    In the expression: Right $ s n

It seems like somehow the compiler has lost track of the fact that s is polymorphic. What happened here and how do I fix it?

like image 829
John F. Miller Avatar asked May 23 '12 22:05

John F. Miller


People also ask

Does genetic variation cause polymorphism?

Polymorphism, as related to genomics, refers to the presence of two or more variant forms of a specific DNA sequence that can occur among different individuals or populations. The most common type of polymorphism involves variation at a single nucleotide (also called a single-nucleotide polymorphism, or SNP).

Does repetitive DNA show polymorphism?

Satellite DNA forms the minor peak after centrifugation of DNA. These are repetitive DNA sequences that do not code for any protein. They show high degree of polymorphism and heritable from parents to children, this form the basis of DNA fingerprinting.

How does balancing selection maintain polymorphism?

Balancing selection, on the other hand, brings the favored allele to an intermediate equilibrium, where it is maintained as a genetic polymorphism that potentially increases the variability in the genomic region nearby the selected locus.

What causes DNA polymorphism?

DNA polymorphisms are produced by changes in the nucleotide sequence or length. These result from: (i) Variations in the fragment length pattern produced after digesting DNA with restriction enzymes, (ii) Variations in the size of a DNA fragment after PCR amplification, and (iii) Variations in the DNA sequence itself.


1 Answers

s is not polymorphic from inside of your function: you can use any function that works on some Num instance as this parameter, it might be a function that only works on Complex! What you need is an universally quantified function s, i.e. one that can actually be called with any Num instance.

{-# LANGUAGE Rank2Types #-}

computeValue :: (forall a . Num a => a->a) -> Integer -> Maybe Double -> Either Double Integer
computeValue s n Nothing = Right $ s n
computeValue s n (Just a) = Left $ s (fromIntegral n + a)

That works then:

Prelude Data.Either> computeValue id 3 Nothing
Right 3
Prelude Data.Either> computeValue negate 57 (Just pi)
Left (-60.1415926535898)
like image 183
leftaroundabout Avatar answered Oct 31 '22 20:10

leftaroundabout