2012-09-20 16 views
8

मैं स्केलास्केला: एक सामान्य पुनरावर्ती अधिकतम समारोह

maximum' :: (Ord a) => [a] -> a 
maximum' [] = error "maximum of empty list" 
maximum' [x] = x 
maximum' (x:xs) = max x (maximum' xs) 

को बंदरगाह के लिए कोशिश कर रहा हूँ इस Haskell अधिकतम समारोह कार्यान्वयन को लागू यह मेरा पहला प्रयास है:

def max[T <: Ordered[T]](list: List[T]): T = list match { 

    case Nil => throw new Error("maximum of empty list") 
    case head :: Nil => head 
    case list => { 
    val maxTail = max(list.tail) 
    if (list.head > maxTail) list.head else maxTail 
    } 
} 


max(List[Int](3,4)) 

लेकिन मैं निम्नलिखित त्रुटि मिलती है :

inferred type arguments [Int] do not conform to method max's type parameter bounds [T <: Ordered[T]] 

मैं आदेश, comprable, इसी तरह के परिणाम के साथ आदि के साथ की कोशिश की ...

012,

क्या गुम है के बारे में कोई विचार?

उत्तर

13

शायद आप Ordering टाइप क्लास चाहते हैं?

def max[T: Ordering](list: List[T]): T = list match { 
    case Nil => throw new RuntimeException("maximum of empty list") 
    case head :: Nil => head 
    case list => 
    val maxTail = max(list.tail) 
    if (implicitly[Ordering[T]].gt(list.head, maxTail)) list.head else maxTail 
} 

यह है, सब के बाद, कैसे निर्मित max विधि काम करता है:

// From GenTraversableOnce 
def max[A1 >: A](implicit ord: Ordering[A1]): A 

आप चीजों को एक बहुत साफ कर सकते हैं अगर आप ऐसा करते हैं:

def max[T](list: List[T])(implicit ord: Ordering[T]): T = list match { 
    case Nil => throw new RuntimeException("maximum of empty list") 
    case head :: Nil => head 
    case head :: tail => ord.max(head, max(tail)) 
} 

या, आप इसे बढ़ी हुई दक्षता के लिए पूंछ-रिकर्सिव बना सकते हैं (क्योंकि संकलक इसे अनुकूलित करेगा):

def max[T](list: List[T])(implicit ord: Ordering[T]): T = { 
    if (list.isEmpty) 
    throw new RuntimeException("maximum of empty list") 

    @tailrec 
    def inner(list: List[T], currMax: T): T = 
    list match { 
     case Nil => currMax 
     case head :: tail => inner(tail, ord.max(head, currMax)) 
    } 
    inner(list.tail, list.head) 
} 

इसके अलावा, आपको RuntimeException या इसके उप-वर्ग को फेंकना चाहिए, Error नहीं।

+0

+1 ...(मेरे पास अभी भी पर्याप्त साहस नहीं है ... स्रोत का उपयोग करें !!!) – opensas

+0

मुझे लगता है कि ord.max का उपयोग करना धोखाधड़ी की तरह होगा, मैं इसे केवल शैक्षणिक उद्देश्यों के लिए कर रहा हूं ... वैसे भी, मैंने अधिकतम एलिमेंटमेंट हेल्पर बनाया वहां उस वैल से बचने के लिए कार्य करें ... – opensas

+1

'ord.max' 'List.max' से अलग है। एक मूल रूप से एक ऑपरेटर है जो दो चीजों की तुलना करता है जबकि दूसरा एक संपूर्ण संग्रह की विधि है। वे सिर्फ वही नाम होने लगते हैं। – dhg

0

ओह, चाहिये

पूछ मैं इस धागे में जवाब मिल गया से पहले बेहतर दिखेगा: https://stackoverflow.com/a/691674/47633

ऐसा लगता है हास्केल के प्रकार वर्गों की तरह स्केला में (DHG के उदाहरण की तरह)

implicits का उपयोग करके लागू तो यह इस तरह समाप्त होता है:

def max[T](list: List[T])(implicit f: T => Ordered[T]): T = { 

def maxElement(value1: T, value2: T): T = if (value1 > value2) value1 else value2 

list match { 
    case Nil => throw new Error("empty list found") 
    case head :: Nil => head 
    case list => maxElement(list.head, max(list.tail)) 
    } 
} 

या कुछ वाक्यात्मक चीनी के साथ, बस

def max[T <% Ordered[T]](list: List[T]): T = list match { 

फिर भी, मुझे लगता है कि संकलक खुद से यह करने के लिए पर्याप्त जानकारी है ...

ps: मैं एक छोटा सा समारोह ...

5

मैं सिर्फ आए हैं अप prettied इस समाधान के साथ।

def max(xs: List[Int]): Int = { 
    if (xs.isEmpty) 0 
    else { 
     if(xs.head >= max(xs.tail)) xs.head 
     else max(xs.tail) 
    } 
} 
+2

मुझे लगता है कि यह एक सामान्य समाधान – opensas

+0

@ ओपेन्सस नहीं है, लेकिन मैं इसे सबसे प्रासंगिक प्रश्न से जोड़ना चाहता हूं, वर्तमान में यह एक है । – eomeroff

+3

@eomeroff बंद करें, लेकिन आपका समाधान नकारात्मक संख्याओं के लिए काम नहीं करता है (अधिकतम (सूची (-3, -7, -2) ') का प्रयास करें। इसे 'if' to' if (xs) को संशोधित करके हल किया जा सकता है .tail.isEmpty || xs.head> = max (xs.tail)) ' – supermasher

1

मैं समझने में आसान एक सरल समाधान के साथ आया था। यह एक खाली सूची, केवल एक तत्व के साथ एक सूची, और नकारात्मक संख्या के लिए पूरा करता है।

def max(xs: List[Int]): Int = { 

    if (xs.isEmpty) throw new NoSuchElementException 
    else { 
    def inner(max: Int, list: List[Int]): Int = { 

     def compare(x: Int, y: Int): Int = 
     if (x > y) x 
     else y 

     if (list.isEmpty) max 
     else inner(compare(max, list.head), list.tail) 
    } 
    inner(xs.head, xs.tail) 
    } 
} 
16

ओपी बिना पैटर्न मिलान और सामान्य प्रकार के रूप में एक ऐसी ही व्यायाम के माध्यम से चला गया, और निम्नलिखित के साथ आया था: स्रोत पर एक नज़र रखने के लिए

def max(xs: List[Int]): Int = { 
    if (xs.isEmpty) throw new NoSuchElementException 

    if (xs.length == 1) 
     return xs.head 
     else 
     return max(xs.head, max(xs.tail)) 
    } 

    def max(x: Int, y: Int): Int = if (x > y) x else y 
+1

> अधिकतम अधिकतम (xs.head, max (xs.tail)) आप यह कॉल नहीं कर सकते हैं, क्योंकि आपके पास कोई फ़ंक्शन अधिकतम नहीं है (एक्स: इंट, एक्सएस: सूची [Int]) परिभाषित। – fkoksal

संबंधित मुद्दे