μ°μ€μ€ λ©μ§λλ€! C#μ΄ μ¬μ€ λ§μ΄ νλν λμμ§μ.
κ·Έλ μ΅λλ€.
κ·Έλ°λ°, F# μ½λλ₯Ό 보λ, μλ ν¨ν΄ 맀μΉμ λν μ§μμ΄ μμΌλ©΄, μ’μ κ² κ°λ€λ μκ°μ ν΄λ΄ λλ€.
// => source.Any() is false ? []
=> source is [] ? []
μ¬μ€, Linq νμ₯ λ©μλμ IsEmpty()κ° μμ΄μ, νμ λ³λλ‘ μ μν΄μ μ°κ³€ νκ±°λ μ.
public static bool IsEmpty(this IEnumerable<T> source) => !source.Any();
μ΄λ κ² μ μνλ©΄, μ½λ κ°λ μ±μ΄ μ’μμ§λλ€.
// => source.Any() is false ? []
=> source.IsEmpty() ? []
μ΄κ²λ³΄λ€λ ν¨ν΄ 맀μΉμ΄ λ μ’μ κ² κ°μ΅λλ€.
μΆκ°
κ°μκΈ°, F# μ΄ List λ₯Ό μ¬μ©νλ€λ μκ°μ΄ λ¬μ΅λλ€. C# λ List λ₯Ό μ¬μ©νλ©΄,
public static List<T> QuickSort<T>(this List<T> source)
where T : IComparable<T> => source is [] ? []
:[
.. source[1..].FindAll(x => x.CompareTo(source[0]) < 0).QuickSort(),
source[0],
.. source[1..].FindAll(x => x.CompareTo(source[0]) >= 0).QuickSort(),
];
F#κ³Ό C# λΉκ΅ : μΉ νμ΄μ§ λ€μ΄λ‘λ
μ¬μ€ λ³Έλ¬Έ λ΄μ©μ κ·Ήμ μΈ λΉκ΅λ C#μ΄ μμ§ using xxx; λ¬Έλ²μ μ§μνμ§ μμλ κ³Όκ±°μ κΈ°μ€μ΄κΈ°λ ν©λλ€.
F#μμ νΉμ μΉ νμ΄μ§λ₯Ό λ€μ΄λ‘λ νκ³ ν μ€νΈ μ€νΈλ¦Όμ μ²λ¦¬νλ μ½λ°±μΌλ‘ μ΄λ₯Ό μ²λ¦¬νλ μ½λλ₯Ό μ΄ν΄λ΄ μλ€.
open System.Net
open System
open System.IO
let fetchUrl callback url =
let req = WebRequest.Create(Uri(url))
use resp = req.GetResponse()
use stream = resp.GetResponseStream()
use reader = new IO.StreamReader(stream)
callback reader url
μ΄μ ν΄λΉνλ C# μ½λλ,
class WebPageDownloader
{
public TResult FetchUrl<TResult>(
string url,
Func<string, StreamReader, TResult> callback)
{
var req = WebRequest.Create(url);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
return callback(url, reader);
}
}
}
}
}
μΌλ‘ κ°λ μ±μ΄ λ§μ΄ λ¨μ΄μ§λλ€. λ¬Όλ‘ ,
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
}
μΌλ‘ μ€κ΄νΈλ₯Ό μ κ±°ν μ μμ§λ§ λ³΄λ€ μΌλ°μ μΈ κ²½μ°μλ νμν©λλ€.
C#μ μ΅κ·Ό λ¬Έλ²μλ λ€μκ³Ό κ°μ΄ μΈ μ μμ΅λλ€.
using var resp = req.GetResponse(); using var stream = resp.GetResponseStream(); using var reader = new StreamReader(stream);
κ·Έλ° λ€μ myCallback
μ λ€μμ²λΌ μμ±ν ν μ¬μ©ν μ μμ΅λλ€.
let myCallback (reader:IO.StreamReader) url =
let html = reader.ReadToEnd()
let html1000 = html.Substring(0,1000)
printfn "Downloaded %s. First 1000 is %s" url html1000
html
let google = fetchUrl myCallback "http://google.com"
F#μ λλ€λ₯Έ μ μ©ν κΈ°λ₯μΌλ‘ `λ² μ΄ν¬ μΈ" ν μ μλλ‘ λ§€κ°λ³μλ₯Ό λ§€λ² μ λ¬νμ§ μμλ λ©λλ€.
//λ² μ΄ν¬ μΈ νμ¬ myCallbackλ₯Ό κΈ°λ³ΈμΌλ‘ μ¬μ©νλ μλ‘μ΄ ν¨μλ₯Ό λ§λ¬
let fetchUrl2 = fetchUrl myCallback
/ test
let google = fetchUrl2 "http://www.google.com"
let bbc = fetchUrl2 "http://news.bbc.co.uk"
let sites = ["http://www.bing.com";
"http://www.google.com";
"http://www.yahoo.com"]
sites |> List.map fetchUrl2
μ΄μ λλ±ν C#μ½λλ λ€μκ³Ό κ°μ΅λλ€.
[Test]
public void TestFetchUrlWithCallback()
{
Func<string, StreamReader, string> myCallback = (url, reader) =>
{
var html = reader.ReadToEnd();
var html1000 = html.Substring(0, 1000);
Console.WriteLine(
"Downloaded {0}. First 1000 is {1}", url,
html1000);
return html;
};
var downloader = new WebPageDownloader();
var google = downloader.FetchUrl("http://www.google.com",
myCallback);
// test with a list of sites
var sites = new List<string> {
"http://www.bing.com",
"http://www.google.com",
"http://www.yahoo.com"};
// process each site in the list
sites.ForEach(site => downloader.FetchUrl(site, myCallback));
}
νλ C#μ μ΄μ F#κ³Ό κ±°μ λμΌν μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
var myCallback = (string url, StreamReader reader) =>
{
var html = reader.ReadToEnd();
var html100 = html[..100];
Console.WriteLine($"Downloaded {url}. First 1000 is {html100}");
return html;
};
var fetchUrl2 = (string url) => WebPageDownloader.FetchUrl(url, myCallback);
var google = fetchUrl2("http://www.google.com");
var bbc = fetchUrl2("http://news.bbc.co.uk");
List<string> sites = [
"http://www.bing.com",
"http://www.google.com",
"http://www.yahoo.com"];
sites.ForEach(i => fetchUrl2(i));
νλ C#μ μ΄λ₯΄λ¬ κ·Έ κ²©μ°¨κ° μ€κΈ΄ νμ§λ§ C#μ λ°μ λ°©ν₯μ΄ F#μ μ₯μ μ μ«κ³ μμμμ μ μ μμλ€μ.
F#μ 4κ°μ§ ν΅μ¬ κ°λ
λ΄μ©μ μ΄ν΄νλ κ²κ³Ό μ΄ν΄ν κ²μΌλ‘ ν μ μλ κ²μ νλκ³Ό λ μ°¨μ΄μ λλ€. μ¬μ¬ F#μ μ₯μ κ³Ό νΉμ§μ΄ νμ λκ³ μμ΅λλ€. λ²μ¨ λ©°μΉ μ΄ μ§λ¬κ΅°μ!
F#μ κ°λ ₯ν ν¨μν μΈμ΄λ‘ ꡬμ¬ν μ μκΈ° λλ¬Έμ λ€μμ νΉμ§μ μ΄ν΄λ΄μΌ ν©λλ€.
- κ°μ²΄ μ§ν₯ 보λ€λ ν¨μ μ§ν₯
- Statement 보λ€λ Expression
μ½λ λ¨μμΈ Expressionκ³Ό Statementμ μ°¨μ΄λ₯Ό μμ보μ - Parkito's on the way - λλ©μΈ λͺ¨λΈμ μν λμ μ ν
- μ μ΄ νλ¦μ μν ν¨ν΄ 맀μΉ
C# μΈμ΄λ μ΄μ ν¨μν μΈμ΄μ μ¬λ¬ μ₯μ μ μ·¨νκ³ μμ΅λλ€. κ·Έμ€ ν¨ν΄ 맀μΉλ μμ΅λλ€.
κ°μ²΄ μ§ν₯ 보λ€λ ν¨μ μ§ν₯
κ°μ²΄ μ§ν₯ ν¨λ¬λ€μμ μν μ κ°μ²΄
μ λμλ κ²μ
λλ€. κ·Έλμ μνμ νμκ° κ°μ²΄
λΌλ μ€λΈμ νΈλ‘ μ‘΄μ¬νκ² λ©λλ€. μ΄μ λ°ν΄ ν¨μ μ§ν₯μ λ°μ΄ν°
κ° μ€μ¬μ΄ λμ΄μ λ°μ΄ν°μ νλ¦μ μ§μ€ ν©λλ€. κ·Έλ¦¬κ³ λ€μμ νΉμ§μ ν΅ν΄ λ¬Έμ λ₯Ό νλλ€.
- κ²°ν©(Composition)
ν¨μ μ§ν₯ νλ‘κ·Έλλ°μ μμ λ¨μλ₯Ό κ²°ν©νμ¬ ν° λ¬Έμ λ₯Ό νΈλλ° μ ν©ν©λλ€. μ΄λ κ°μ²΄ μ§ν₯μ μΈν°νμ΄μ€λ₯Ό ν΅ν κ²°ν©κ³Ό μ μ¬ν μ μ΄ μμ΅λλ€. - λΆν΄μ 리ν©ν λ§
ν¨μ μ§ν₯μ κ°μ²΄ μ§ν₯μΌλ‘ λλ μ μλ κ² μ΄μμΌλ‘ ν¨μ λ¨μλ‘ λλ μ μμ΄μ μ€λ³΅ μ½λλ₯Ό μ’ λ μ΅μ νκ³ μ½λ μ½κΈ°κ° νΈλ¦¬ ν©λλ€. - μ’μ λμμΈ
ν¨μν μ κ·Ό λ°©μμ μν΄μ μμ°μ€λ½κ²κ΄μ¬μ¬ λΆλ¦¬
,λ¨μΌ μ± μ μμΉ
,ꡬνμ΄ μλ μΈν°νμ΄μ€
λ± μ’μ λμμΈ μ€ λ§μ λΆλΆμ ν¨μν μ κ·Ό λ°©μμ μμ°μ€λ¬μ΄ κ²°κ³Όμ λλ€.
λ¬Έμ₯(Statement) 보λ€λ ννμ(Expression)
F#μ ν¨μμ μν΄ λͺ¨λ μ½λ λΈλμ κ°κ³Ό κΉκ² μ°κ΄λμ΄ μκ³ κ°μ λ°νν©λλ€. λ ν° μ½λ λΈλμ κ²°ν©μ ν΅ν΄ λ μμ λΈλμ κ²°ν©νμ¬ λ§λ€μ΄μ§λλ€.
ννμ κΈ°λ°μ΄λ LINQμ SQLκ³Ό κ°μ ννμ λλ€.
λμ μ ν
F#μ λ¨μν μ νμ κ²°ν©νμ¬ μ’ λ 볡μ‘ν μ νμ λ§λ€μ΄ νμ©ν©λλ€. μ΄λ μΌλ° μΈμ΄μ structμΌλ‘ μκ°ν μ μλλ° μ λμ¨ μ νμ νΉμ§μΌλ‘ μΌλ° λ³΅ν© μ νκ³Ό ꡬλΆλ©λλ€.
type IntOrBool =
| IntChoice of int
| BoolChoice of bool
let y = IntChoice 42
let z = BoolChoice true
ν¨ν΄ 맀μΉ
ν¨ν΄ 맀μΉμ λͺ¨λ 쑰건μ ν΄λΉνλ κ°μ μ²λ¦¬ν μ μλλ‘ ν©λλ€.
match booleanExpression with
| true -> // true branch
| false -> // false branch
match aDigit with
| 1 -> // Case when digit=1
| 2 -> // Case when digit=2
| _ -> // Case otherwise
match aList with
| [] ->
// Empty case
| first::rest ->
μ΄λ κ°λ ₯ν΄μ C#μμλ μ΄μ μ¬μ© κ°λ₯ ν©λλ€.
μ λμ¨ μ νμ μ¬μ©ν ν¨ν΄ 맀μΉ
μ΄ κΈ°λ₯μ λ§€μ° κ°λ ₯ν΄μ Rust λ± μ΅μ νλ‘κ·Έλλ° μΈμ΄μμ μ¬μ©λκ³ μμΌλ©° λΉ λ₯΄κ³ μ ννλ©° ν¨μ¨μ μΈ μλ£νμ λν μ²λ¦¬λ₯Ό κ°λ₯νκ² ν©λλ€.
type Shape = // define a "union" of alternative structures
| Circle of radius:int
| Rectangle of height:int * width:int
| Point of x:int * y:int
| Polygon of pointList:(int * int) list
let draw shape = // define a function "draw" with a shape param
match shape with
| Circle radius ->
printfn "The circle has a radius of %d" radius
| Rectangle (height,width) ->
printfn "The rectangle is %d high by %d wide" height width
| Polygon points ->
printfn "The polygon is made of these points %A" points
| _ -> printfn "I don't recognize this shape"
let circle = Circle(10)
let rect = Rectangle(4,5)
let point = Point(2,3)
let polygon = Polygon( [(1,1); (2,2); (3,3)])
[circle; rect; polygon; point] |> List.iter draw
νλ μ§ν₯ λ λ°μ΄ν° μ§ν₯ λμμΈ
μ΄λ¬ν ν¨ν΄ 맀μΉμ κ°μ²΄ μ§ν₯μ κ΄μ μμλ λͺ¨λ μ νμ λν λΆκΈ°κ° μΌμ΄λλ―λ‘ μν°ν¨ν΄ μ²λΌ 보μ
λλ€. κ°μ²΄ μ§ν₯μμλ μΆμνλ₯Ό ν΅ν΄ μ΄λ€ μ νμ΄λ μ§ λμΌνκ² μ²λ¦¬νλλ‘ νλ κ²μ μ§ν₯νλλ°μ,
F#μμλ μ΄κ²μ μ λμ¨ νμ
μΌλ‘ ν΄κ²°ν©λλ€.