Haskell:在自定义数据类型中找到最小值

时间:2016-09-25 20:59:51

标签: haskell

所以我有一个自定义数据类型,我们称之为09-26 02:20:32.209 27677-27897/com.gis.reliance.customercomplaintreports E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 Process: com.gis.reliance.customercomplaintreports, PID: 27677 java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.VerifyError: org/ksoap2/SoapEnvelope at com.gis.reliance.customercomplaintreports.activity.LoginActivity.isAuthenticate(LoginActivity.java:141) at com.gis.reliance.customercomplaintreports.activity.LoginActivity$AsyncCallWS.doInBackground(LoginActivity.java:160) at com.gis.reliance.customercomplaintreports.activity.LoginActivity$AsyncCallWS.doInBackground(LoginActivity.java:157) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)  at java.lang.Thread.run(Thread.java:841)  ,定义如下:

Struct

我需要做的是浏览data Struct = Struct [SubStruct] deriving (Read, Show) data SubStruct = SubStruct (Int, Int) deriving (Read, Show) 中的所有元素,并根据Struct找到最小值,然后根据fst。我怎么做? 更具体地说,我想获得另一个snd,例如:

SubStruct,基于代码中的示例。

目前,我开始这样做:

SubStruct (-2,-5)

但是我收到了这个错误:

import Data.List
import Data.Function (on)
import Data.List (sortBy)

data Struct = Struct  [SubStruct] deriving (Read, Show)
data SubStruct = SubStruct (Int, Int) deriving (Read, Show  )

struct s sx = Struct(s:sx)

subStruct :: (Int, Int) -> SubStruct
subStruct (x, y) = SubStruct (x, y)

substructs = Struct $ [subStruct (0,1), subStruct (-2, 3), subStruct (4,-5)]

results xs = sortBy (compare `on` fst) (substructs xs)

2 个答案:

答案 0 :(得分:6)

为什么不使用unzip功能。如果我们定义一个辅助函数:

unSubStruct :: SubStruct -> (Int, Int)
unSubStruct (SubStruct p) = p

然后返回所需元素的函数可以写成:

getMin :: Struct -> SubStruct
getMin (Struct l) = SubStruct (minimum xs, minimum ys)
  where
    (xs, ys) = unzip $ map unSubStruct l

请注意,这将遍历列表两次。如果您定义适用于对的自己的版本minimum,则可以避免这种情况:

getMin :: Struct -> SubStruct
getMin (Struct l) =
    SubStruct $ foldr1 minPair $ map unSubStruct l
  where
    minPair (x0, y0) (x, y) = (min x0 x, min y0 y)

答案 1 :(得分:0)

您有一个SubStruct列表,它与元组列表基本相同。

因此,仅使用常用函数的一种解决方案是:

result = SubStruct (min1, min2) where
    min1 = minimum (map fst . list)
    min2 = minimum (map snd . list)
    list = case substructs of
         Struct this -> map (\(SubStruct t) -> t) this