所以我有一个自定义数据类型Person
data Person = Person{ fname :: String
, lname :: String
, age :: Int
, siblings :: [String]
}
我有一个这种类型的列表,foo = [Person].
我正在尝试更新特定的Person
。我的流程是匹配他们的fname
(假设每个名称都是唯一的),然后更新他们的siblings
值。
addSiblingToPerson :: String -> String -> [Person] -> [Person]
addSiblingToPerson siblingParam fnameParam fooParam =
我真的在努力思考“功能性”,如果我用命令式语言这样做,我可以通过[Person]
检查if name == fname then this.siblings push newSibling
中的每个项目来查看Person
(或者沿着这些行)
我知道如何更新haskell中的记录,但我希望在更新Person
集合中的单个人后返回public class GetLocationDownloadTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
String result = "";
URL url;
HttpURLConnection urlConnection;
try {
url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream is = urlConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(is);
int data = inputStreamReader.read();
while(data != -1){
char curr = (char) data;
result += curr;
data = inputStreamReader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null) {
try {
JSONObject locationObject = new JSONObject(result);
JSONObject locationGeo = locationObject.getJSONArray("results").getJSONObject(0).getJSONObject("geometry").getJSONObject("location");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
列表。
我无法理解如何“思考Haskell”
谢谢:(
答案 0 :(得分:1)
你不应该考虑&#34;更新&#34;某些东西,即使我们使用那个术语,除非你有一个可变的引用并且正在使用IO monad。在这种情况下,思考过程应该是&#34;我如何计算一个与前一个完全相同的新列表,除了......&#34;。
您可以在整个列表中更新单个条目或map
修改功能。让我们先看一下手册,单项,解决方案:
addSiblingToPerson :: String -> String -> [Person] -> [Person]
addSiblingToPerson siblingParam fnameParam allPeople =
case allPeople of
[] -> []
(p:ps) | fname p == fnameParam ->
p { siblings = siblingParam : siblings p } : ps
| otherwise ->
p : addSiblingToPerson siblingParam fnameParam ps
也就是说,我们遍历列表,保留任何不匹配的人并使用匹配的fname
更新第一个人,确保包含列表的其余部分。
地图解决方案在功能上有所不同 - 它将更新所有共享给定fname
的人,并且它将遍历整个列表。
addSiblingToPerson :: String -> String -> [Person] -> [Person]
addSiblingToPerson siblingParam fnameParam allPeople =
let update p | fname p == fnameParam = p { siblings = siblingParam : siblings p }
| otherwise = p
in map update allPeople